From: Greg Kroah-Hartman Date: Wed, 20 Sep 2023 11:05:00 +0000 (+0200) Subject: 4.14-stable patches X-Git-Tag: v5.10.196~17 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b733f34a07867e2cdea08f115d1195ef5bdefdfa;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: mtd-rawnand-brcmnand-fix-crash-during-the-panic_write.patch mtd-rawnand-brcmnand-fix-ecc-level-field-setting-for-v7.2-controller.patch mtd-rawnand-brcmnand-fix-potential-false-time-out-warning.patch mtd-rawnand-brcmnand-fix-potential-out-of-bounds-access-in-oob-write.patch --- diff --git a/queue-4.14/mtd-rawnand-brcmnand-fix-crash-during-the-panic_write.patch b/queue-4.14/mtd-rawnand-brcmnand-fix-crash-during-the-panic_write.patch new file mode 100644 index 00000000000..25c03dbb21d --- /dev/null +++ b/queue-4.14/mtd-rawnand-brcmnand-fix-crash-during-the-panic_write.patch @@ -0,0 +1,47 @@ +From e66dd317194daae0475fe9e5577c80aa97f16cb9 Mon Sep 17 00:00:00 2001 +From: William Zhang +Date: Thu, 6 Jul 2023 11:29:07 -0700 +Subject: mtd: rawnand: brcmnand: Fix crash during the panic_write + +From: William Zhang + +commit e66dd317194daae0475fe9e5577c80aa97f16cb9 upstream. + +When executing a NAND command within the panic write path, wait for any +pending command instead of calling BUG_ON to avoid crashing while +already crashing. + +Fixes: 27c5b17cd1b1 ("mtd: nand: add NAND driver "library" for Broadcom STB NAND controller") +Signed-off-by: William Zhang +Reviewed-by: Florian Fainelli +Reviewed-by: Kursad Oney +Reviewed-by: Kamal Dasu +Cc: stable@vger.kernel.org +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20230706182909.79151-4-william.zhang@broadcom.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mtd/nand/brcmnand/brcmnand.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +--- a/drivers/mtd/nand/brcmnand/brcmnand.c ++++ b/drivers/mtd/nand/brcmnand/brcmnand.c +@@ -1271,7 +1271,17 @@ static void brcmnand_send_cmd(struct brc + + dev_dbg(ctrl->dev, "send native cmd %d addr 0x%llx\n", cmd, cmd_addr); + +- BUG_ON(ctrl->cmd_pending != 0); ++ /* ++ * If we came here through _panic_write and there is a pending ++ * command, try to wait for it. If it times out, rather than ++ * hitting BUG_ON, just return so we don't crash while crashing. ++ */ ++ if (oops_in_progress) { ++ if (ctrl->cmd_pending && ++ bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY, NAND_CTRL_RDY, 0)) ++ return; ++ } else ++ BUG_ON(ctrl->cmd_pending != 0); + ctrl->cmd_pending = cmd; + + ret = bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY, NAND_CTRL_RDY, 0); diff --git a/queue-4.14/mtd-rawnand-brcmnand-fix-ecc-level-field-setting-for-v7.2-controller.patch b/queue-4.14/mtd-rawnand-brcmnand-fix-ecc-level-field-setting-for-v7.2-controller.patch new file mode 100644 index 00000000000..e759935326c --- /dev/null +++ b/queue-4.14/mtd-rawnand-brcmnand-fix-ecc-level-field-setting-for-v7.2-controller.patch @@ -0,0 +1,155 @@ +From 2ec2839a9062db8a592525a3fdabd42dcd9a3a9b Mon Sep 17 00:00:00 2001 +From: William Zhang +Date: Thu, 6 Jul 2023 11:29:05 -0700 +Subject: mtd: rawnand: brcmnand: Fix ECC level field setting for v7.2 controller + +From: William Zhang + +commit 2ec2839a9062db8a592525a3fdabd42dcd9a3a9b upstream. + +v7.2 controller has different ECC level field size and shift in the acc +control register than its predecessor and successor controller. It needs +to be set specifically. + +Fixes: decba6d47869 ("mtd: brcmnand: Add v7.2 controller support") +Signed-off-by: William Zhang +Reviewed-by: Florian Fainelli +Cc: stable@vger.kernel.org +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20230706182909.79151-2-william.zhang@broadcom.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mtd/nand/brcmnand/brcmnand.c | 74 +++++++++++++++++++---------------- + 1 file changed, 41 insertions(+), 33 deletions(-) + +--- a/drivers/mtd/nand/brcmnand/brcmnand.c ++++ b/drivers/mtd/nand/brcmnand/brcmnand.c +@@ -152,6 +152,7 @@ struct brcmnand_controller { + unsigned int max_page_size; + const unsigned int *page_sizes; + unsigned int max_oob; ++ u32 ecc_level_shift; + u32 features; + + /* for low-power standby/resume only */ +@@ -441,6 +442,34 @@ enum { + INTFC_CTLR_READY = BIT(31), + }; + ++/*********************************************************************** ++ * NAND ACC CONTROL bitfield ++ * ++ * Some bits have remained constant throughout hardware revision, while ++ * others have shifted around. ++ ***********************************************************************/ ++ ++/* Constant for all versions (where supported) */ ++enum { ++ /* See BRCMNAND_HAS_CACHE_MODE */ ++ ACC_CONTROL_CACHE_MODE = BIT(22), ++ ++ /* See BRCMNAND_HAS_PREFETCH */ ++ ACC_CONTROL_PREFETCH = BIT(23), ++ ++ ACC_CONTROL_PAGE_HIT = BIT(24), ++ ACC_CONTROL_WR_PREEMPT = BIT(25), ++ ACC_CONTROL_PARTIAL_PAGE = BIT(26), ++ ACC_CONTROL_RD_ERASED = BIT(27), ++ ACC_CONTROL_FAST_PGM_RDIN = BIT(28), ++ ACC_CONTROL_WR_ECC = BIT(30), ++ ACC_CONTROL_RD_ECC = BIT(31), ++}; ++ ++#define ACC_CONTROL_ECC_SHIFT 16 ++/* Only for v7.2 */ ++#define ACC_CONTROL_ECC_EXT_SHIFT 13 ++ + static inline u32 nand_readreg(struct brcmnand_controller *ctrl, u32 offs) + { + return brcmnand_readl(ctrl->nand_base + offs); +@@ -544,6 +573,12 @@ static int brcmnand_revision_init(struct + else if (of_property_read_bool(ctrl->dev->of_node, "brcm,nand-has-wp")) + ctrl->features |= BRCMNAND_HAS_WP; + ++ /* v7.2 has different ecc level shift in the acc register */ ++ if (ctrl->nand_version == 0x0702) ++ ctrl->ecc_level_shift = ACC_CONTROL_ECC_EXT_SHIFT; ++ else ++ ctrl->ecc_level_shift = ACC_CONTROL_ECC_SHIFT; ++ + return 0; + } + +@@ -697,30 +732,6 @@ static inline int brcmnand_cmd_shift(str + return 0; + } + +-/*********************************************************************** +- * NAND ACC CONTROL bitfield +- * +- * Some bits have remained constant throughout hardware revision, while +- * others have shifted around. +- ***********************************************************************/ +- +-/* Constant for all versions (where supported) */ +-enum { +- /* See BRCMNAND_HAS_CACHE_MODE */ +- ACC_CONTROL_CACHE_MODE = BIT(22), +- +- /* See BRCMNAND_HAS_PREFETCH */ +- ACC_CONTROL_PREFETCH = BIT(23), +- +- ACC_CONTROL_PAGE_HIT = BIT(24), +- ACC_CONTROL_WR_PREEMPT = BIT(25), +- ACC_CONTROL_PARTIAL_PAGE = BIT(26), +- ACC_CONTROL_RD_ERASED = BIT(27), +- ACC_CONTROL_FAST_PGM_RDIN = BIT(28), +- ACC_CONTROL_WR_ECC = BIT(30), +- ACC_CONTROL_RD_ECC = BIT(31), +-}; +- + static inline u32 brcmnand_spare_area_mask(struct brcmnand_controller *ctrl) + { + if (ctrl->nand_version >= 0x0702) +@@ -731,18 +742,15 @@ static inline u32 brcmnand_spare_area_ma + return GENMASK(5, 0); + } + +-#define NAND_ACC_CONTROL_ECC_SHIFT 16 +-#define NAND_ACC_CONTROL_ECC_EXT_SHIFT 13 +- + static inline u32 brcmnand_ecc_level_mask(struct brcmnand_controller *ctrl) + { + u32 mask = (ctrl->nand_version >= 0x0600) ? 0x1f : 0x0f; + +- mask <<= NAND_ACC_CONTROL_ECC_SHIFT; ++ mask <<= ACC_CONTROL_ECC_SHIFT; + + /* v7.2 includes additional ECC levels */ +- if (ctrl->nand_version >= 0x0702) +- mask |= 0x7 << NAND_ACC_CONTROL_ECC_EXT_SHIFT; ++ if (ctrl->nand_version == 0x0702) ++ mask |= 0x7 << ACC_CONTROL_ECC_EXT_SHIFT; + + return mask; + } +@@ -756,8 +764,8 @@ static void brcmnand_set_ecc_enabled(str + + if (en) { + acc_control |= ecc_flags; /* enable RD/WR ECC */ +- acc_control |= host->hwcfg.ecc_level +- << NAND_ACC_CONTROL_ECC_SHIFT; ++ acc_control &= ~brcmnand_ecc_level_mask(ctrl); ++ acc_control |= host->hwcfg.ecc_level << ctrl->ecc_level_shift; + } else { + acc_control &= ~ecc_flags; /* disable RD/WR ECC */ + acc_control &= ~brcmnand_ecc_level_mask(ctrl); +@@ -2082,7 +2090,7 @@ static int brcmnand_set_cfg(struct brcmn + + tmp = nand_readreg(ctrl, acc_control_offs); + tmp &= ~brcmnand_ecc_level_mask(ctrl); +- tmp |= cfg->ecc_level << NAND_ACC_CONTROL_ECC_SHIFT; ++ tmp |= cfg->ecc_level << ctrl->ecc_level_shift; + tmp &= ~brcmnand_spare_area_mask(ctrl); + tmp |= cfg->spare_area_size; + nand_writereg(ctrl, acc_control_offs, tmp); diff --git a/queue-4.14/mtd-rawnand-brcmnand-fix-potential-false-time-out-warning.patch b/queue-4.14/mtd-rawnand-brcmnand-fix-potential-false-time-out-warning.patch new file mode 100644 index 00000000000..d1f5069ab81 --- /dev/null +++ b/queue-4.14/mtd-rawnand-brcmnand-fix-potential-false-time-out-warning.patch @@ -0,0 +1,42 @@ +From 9cc0a598b944816f2968baf2631757f22721b996 Mon Sep 17 00:00:00 2001 +From: William Zhang +Date: Thu, 6 Jul 2023 11:29:06 -0700 +Subject: mtd: rawnand: brcmnand: Fix potential false time out warning + +From: William Zhang + +commit 9cc0a598b944816f2968baf2631757f22721b996 upstream. + +If system is busy during the command status polling function, the driver +may not get the chance to poll the status register till the end of time +out and return the premature status. Do a final check after time out +happens to ensure reading the correct status. + +Fixes: 9d2ee0a60b8b ("mtd: nand: brcmnand: Check flash #WP pin status before nand erase/program") +Signed-off-by: William Zhang +Reviewed-by: Florian Fainelli +Cc: stable@vger.kernel.org +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20230706182909.79151-3-william.zhang@broadcom.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mtd/nand/brcmnand/brcmnand.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/mtd/nand/brcmnand/brcmnand.c ++++ b/drivers/mtd/nand/brcmnand/brcmnand.c +@@ -836,6 +836,14 @@ static int bcmnand_ctrl_poll_status(stru + cpu_relax(); + } while (time_after(limit, jiffies)); + ++ /* ++ * do a final check after time out in case the CPU was busy and the driver ++ * did not get enough time to perform the polling to avoid false alarms ++ */ ++ val = brcmnand_read_reg(ctrl, BRCMNAND_INTFC_STATUS); ++ if ((val & mask) == expected_val) ++ return 0; ++ + dev_warn(ctrl->dev, "timeout on status poll (expected %x got %x)\n", + expected_val, val & mask); + diff --git a/queue-4.14/mtd-rawnand-brcmnand-fix-potential-out-of-bounds-access-in-oob-write.patch b/queue-4.14/mtd-rawnand-brcmnand-fix-potential-out-of-bounds-access-in-oob-write.patch new file mode 100644 index 00000000000..514a35d4e4e --- /dev/null +++ b/queue-4.14/mtd-rawnand-brcmnand-fix-potential-out-of-bounds-access-in-oob-write.patch @@ -0,0 +1,64 @@ +From 5d53244186c9ac58cb88d76a0958ca55b83a15cd Mon Sep 17 00:00:00 2001 +From: William Zhang +Date: Thu, 6 Jul 2023 11:29:08 -0700 +Subject: mtd: rawnand: brcmnand: Fix potential out-of-bounds access in oob write + +From: William Zhang + +commit 5d53244186c9ac58cb88d76a0958ca55b83a15cd upstream. + +When the oob buffer length is not in multiple of words, the oob write +function does out-of-bounds read on the oob source buffer at the last +iteration. Fix that by always checking length limit on the oob buffer +read and fill with 0xff when reaching the end of the buffer to the oob +registers. + +Fixes: 27c5b17cd1b1 ("mtd: nand: add NAND driver "library" for Broadcom STB NAND controller") +Signed-off-by: William Zhang +Reviewed-by: Florian Fainelli +Cc: stable@vger.kernel.org +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20230706182909.79151-5-william.zhang@broadcom.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mtd/nand/brcmnand/brcmnand.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +--- a/drivers/mtd/nand/brcmnand/brcmnand.c ++++ b/drivers/mtd/nand/brcmnand/brcmnand.c +@@ -1229,19 +1229,33 @@ static int write_oob_to_regs(struct brcm + const u8 *oob, int sas, int sector_1k) + { + int tbytes = sas << sector_1k; +- int j; ++ int j, k = 0; ++ u32 last = 0xffffffff; ++ u8 *plast = (u8 *)&last; + + /* Adjust OOB values for 1K sector size */ + if (sector_1k && (i & 0x01)) + tbytes = max(0, tbytes - (int)ctrl->max_oob); + tbytes = min_t(int, tbytes, ctrl->max_oob); + +- for (j = 0; j < tbytes; j += 4) ++ /* ++ * tbytes may not be multiple of words. Make sure we don't read out of ++ * the boundary and stop at last word. ++ */ ++ for (j = 0; (j + 3) < tbytes; j += 4) + oob_reg_write(ctrl, j, + (oob[j + 0] << 24) | + (oob[j + 1] << 16) | + (oob[j + 2] << 8) | + (oob[j + 3] << 0)); ++ ++ /* handle the remaing bytes */ ++ while (j < tbytes) ++ plast[k++] = oob[j++]; ++ ++ if (tbytes & 0x3) ++ oob_reg_write(ctrl, (tbytes & ~0x3), (__force u32)cpu_to_be32(last)); ++ + return tbytes; + } + diff --git a/queue-4.14/series b/queue-4.14/series index 6e85fdfd9a3..131dd59024f 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -178,3 +178,7 @@ md-raid1-fix-error-iso-c90-forbids-mixed-declaration.patch attr-block-mode-changes-of-symlinks.patch btrfs-fix-lockdep-splat-and-potential-deadlock-after-failure-running-delayed-items.patch nfsd-fix-change_info-in-nfsv4-rename-replies.patch +mtd-rawnand-brcmnand-fix-crash-during-the-panic_write.patch +mtd-rawnand-brcmnand-fix-potential-false-time-out-warning.patch +mtd-rawnand-brcmnand-fix-ecc-level-field-setting-for-v7.2-controller.patch +mtd-rawnand-brcmnand-fix-potential-out-of-bounds-access-in-oob-write.patch