4.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jean-Philippe Brucker jean-philippe@linaro.org
[ Upstream commit b359ed5184aebf9d987e54abc5dae7ac03ed29ae ]
The flash controller implemented by the Arm Base platform behaves like the Intel StrataFlash J3 device, but omits several features. In particular it doesn't implement a protection register, so "Number of Protection register fields" in the Primary Vendor-Specific Extended Query, is 0.
The Intel StrataFlash J3 datasheet only lists 1 as a valid value for NumProtectionFields. It describes the field as:
"Number of Protection register fields in JEDEC ID space. “00h,” indicates that 256 protection bytes are available"
While a value of 0 may arguably not be architecturally valid, the driver's current behavior is certainly wrong: if NumProtectionFields is 0, read_pri_intelext() adds a negative value to the unsigned extra_size, and ends up in an infinite loop.
Fix it by ignoring a NumProtectionFields of 0.
Signed-off-by: Jean-Philippe Brucker jean-philippe@linaro.org Tested-by: Sudeep Holla sudeep.holla@arm.com Tested-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Vignesh Raghavendra vigneshr@ti.com Stable-dep-of: 565fe150624e ("mtd: cfi_cmdset_0001: Byte swap OTP info") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/chips/cfi_cmdset_0001.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 6e8e7b1bb34b6..e5cf4911a714a 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -420,8 +420,9 @@ read_pri_intelext(struct map_info *map, __u16 adr) extra_size = 0;
/* Protection Register info */ - extra_size += (extp->NumProtectionFields - 1) * - sizeof(struct cfi_intelext_otpinfo); + if (extp->NumProtectionFields) + extra_size += (extp->NumProtectionFields - 1) * + sizeof(struct cfi_intelext_otpinfo); }
if (extp->MinorVersion >= '1') { @@ -695,14 +696,16 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd, */ if (extp && extp->MajorVersion == '1' && extp->MinorVersion >= '3' && extp->FeatureSupport & (1 << 9)) { + int offs = 0; struct cfi_private *newcfi; struct flchip *chip; struct flchip_shared *shared; - int offs, numregions, numparts, partshift, numvirtchips, i, j; + int numregions, numparts, partshift, numvirtchips, i, j;
/* Protection Register info */ - offs = (extp->NumProtectionFields - 1) * - sizeof(struct cfi_intelext_otpinfo); + if (extp->NumProtectionFields) + offs = (extp->NumProtectionFields - 1) * + sizeof(struct cfi_intelext_otpinfo);
/* Burst Read info */ offs += extp->extra[offs+1]+2;