linux-mtd.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] mtd: afs: Support AFSv2 parsing
@ 2019-01-28 13:54 Linus Walleij
  2019-01-28 13:54 ` [PATCH 1/6] mtd: afs: simplify partition parsing Linus Walleij
                   ` (6 more replies)
  0 siblings, 7 replies; 12+ messages in thread
From: Linus Walleij @ 2019-01-28 13:54 UTC (permalink / raw)
  To: David Woodhouse, Brian Norris, Boris Brezillon, Marek Vasut,
	Richard Weinberger, Cyrille Pitchen, linux-mtd
  Cc: Linus Walleij

The later versions of the ARM reference designs use
AFSv2 with a new type of firmware header than in the
v1 version found in earlier versions.

Extend the AFS partition parser to suppoer AFSv2.

This is based on the earlier patch set moving the
parser down to the parsers folder and adding device
tree probing, so it should be applied only after
that series.

Linus Walleij (6):
  mtd: afs: simplify partition parsing
  mtd: afs: simplify partition detection
  mtd: factor out v1 partition parsing
  mtd: afs: factor footer parsing into the v1 part parsing
  mtd: afs: factor the IIS read into partition parser
  mtd: afs: add v2 partition parsing

 drivers/mtd/parsers/afs.c | 369 ++++++++++++++++++++++++++------------
 1 file changed, 253 insertions(+), 116 deletions(-)

-- 
2.20.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/6] mtd: afs: simplify partition parsing
  2019-01-28 13:54 [PATCH 0/6] mtd: afs: Support AFSv2 parsing Linus Walleij
@ 2019-01-28 13:54 ` Linus Walleij
  2019-01-31 17:13   ` Liviu Dudau
  2019-02-12 14:31   ` Liviu Dudau
  2019-01-28 13:54 ` [PATCH 2/6] mtd: afs: simplify partition detection Linus Walleij
                   ` (5 subsequent siblings)
  6 siblings, 2 replies; 12+ messages in thread
From: Linus Walleij @ 2019-01-28 13:54 UTC (permalink / raw)
  To: David Woodhouse, Brian Norris, Boris Brezillon, Marek Vasut,
	Richard Weinberger, Cyrille Pitchen, linux-mtd
  Cc: Linus Walleij, Liviu Dudau, Ryan Harkin

This simplifies the AFS partition parsing to make the code
more straight-forward and readable.

Before this patch the code tried to calculate the memory required
to hold the partition info by adding up the sizes of the strings
of the names and adding that to a single memory allocation,
indexing the name pointers in front of the struct mtd_partition
allocations so all allocated data was in one chunk.

This is overzealous. Instead use kstrdup and bail out,
kfree():ing the memory used for MTD partitions and names alike
on the errorpath.

In the process rename the index variable from idx to i.

Cc: Ryan Harkin <ryan.harkin@linaro.org>
Cc: Liviu Dudau <liviu.dudau@arm.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/mtd/parsers/afs.c | 67 +++++++++++++++++++--------------------
 1 file changed, 32 insertions(+), 35 deletions(-)

diff --git a/drivers/mtd/parsers/afs.c b/drivers/mtd/parsers/afs.c
index 3679e1d22595..c489938cd665 100644
--- a/drivers/mtd/parsers/afs.c
+++ b/drivers/mtd/parsers/afs.c
@@ -166,9 +166,9 @@ static int parse_afs_partitions(struct mtd_info *mtd,
 				struct mtd_part_parser_data *data)
 {
 	struct mtd_partition *parts;
-	u_int mask, off, idx, sz;
+	u_int mask, off, sz;
 	int ret = 0;
-	char *str;
+	int i;
 
 	/*
 	 * This is the address mask; we use this to mask off out of
@@ -181,78 +181,75 @@ static int parse_afs_partitions(struct mtd_info *mtd,
 	 * partition information.  We include in this the size of
 	 * the strings.
 	 */
-	for (idx = off = sz = 0; off < mtd->size; off += mtd->erasesize) {
-		struct image_info_v1 iis;
+	for (i = off = sz = 0; off < mtd->size; off += mtd->erasesize) {
 		u_int iis_ptr, img_ptr;
 
 		ret = afs_read_footer_v1(mtd, &img_ptr, &iis_ptr, off, mask);
 		if (ret < 0)
-			break;
+			return ret;
 		if (ret) {
-			ret = afs_read_iis_v1(mtd, &iis, iis_ptr);
-			if (ret < 0)
-				break;
-			if (ret == 0)
-				continue;
-
 			sz += sizeof(struct mtd_partition);
-			sz += strlen(iis.name) + 1;
-			idx += 1;
+			i += 1;
 		}
 	}
 
-	if (!sz)
-		return ret;
+	if (!i)
+		return 0;
 
 	parts = kzalloc(sz, GFP_KERNEL);
 	if (!parts)
 		return -ENOMEM;
 
-	str = (char *)(parts + idx);
-
 	/*
 	 * Identify the partitions
 	 */
-	for (idx = off = 0; off < mtd->size; off += mtd->erasesize) {
+	for (i = off = 0; off < mtd->size; off += mtd->erasesize) {
 		struct image_info_v1 iis;
 		u_int iis_ptr, img_ptr;
 
 		/* Read the footer. */
 		ret = afs_read_footer_v1(mtd, &img_ptr, &iis_ptr, off, mask);
 		if (ret < 0)
-			break;
+			goto out_free_parts;
 		if (ret == 0)
 			continue;
 
 		/* Read the image info block */
 		ret = afs_read_iis_v1(mtd, &iis, iis_ptr);
 		if (ret < 0)
-			break;
+			goto out_free_parts;
 		if (ret == 0)
 			continue;
 
-		strcpy(str, iis.name);
+		parts[i].name = kstrdup(iis.name, GFP_KERNEL);
+		if (!parts[i].name) {
+			ret = -ENOMEM;
+			goto out_free_parts;
+		}
 
-		parts[idx].name		= str;
-		parts[idx].size		= (iis.length + mtd->erasesize - 1) & ~(mtd->erasesize - 1);
-		parts[idx].offset	= img_ptr;
-		parts[idx].mask_flags	= 0;
+		parts[i].size		= (iis.length + mtd->erasesize - 1) & ~(mtd->erasesize - 1);
+		parts[i].offset	= img_ptr;
+		parts[i].mask_flags	= 0;
 
 		printk("  mtd%d: at 0x%08x, %5lluKiB, %8u, %s\n",
-			idx, img_ptr, parts[idx].size / 1024,
-			iis.imageNumber, str);
-
-		idx += 1;
-		str = str + strlen(iis.name) + 1;
-	}
+			i, img_ptr, parts[i].size / 1024,
+			iis.imageNumber, parts[i].name);
 
-	if (!idx) {
-		kfree(parts);
-		parts = NULL;
+		i += 1;
 	}
 
 	*pparts = parts;
-	return idx ? idx : ret;
+	return i;
+
+out_free_parts:
+	while (i >= 0) {
+		if (parts[i].name)
+			kfree(parts[i].name);
+		i--;
+	}
+	kfree(parts);
+	*pparts = NULL;
+	return ret;
 }
 
 static const struct of_device_id mtd_parser_afs_of_match_table[] = {
-- 
2.20.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/6] mtd: afs: simplify partition detection
  2019-01-28 13:54 [PATCH 0/6] mtd: afs: Support AFSv2 parsing Linus Walleij
  2019-01-28 13:54 ` [PATCH 1/6] mtd: afs: simplify partition parsing Linus Walleij
@ 2019-01-28 13:54 ` Linus Walleij
  2019-01-28 13:54 ` [PATCH 3/6] mtd: factor out v1 partition parsing Linus Walleij
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Linus Walleij @ 2019-01-28 13:54 UTC (permalink / raw)
  To: David Woodhouse, Brian Norris, Boris Brezillon, Marek Vasut,
	Richard Weinberger, Cyrille Pitchen, linux-mtd
  Cc: Linus Walleij, Liviu Dudau, Ryan Harkin

Instead of reading out the AFS footers twice, create a separate
function to just check if there is a footer or not. Rids a few
local variables and prepare us to join the actual parser into
one function.

Cc: Ryan Harkin <ryan.harkin@linaro.org>
Cc: Liviu Dudau <liviu.dudau@arm.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/mtd/parsers/afs.c | 33 ++++++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/parsers/afs.c b/drivers/mtd/parsers/afs.c
index c489938cd665..ccc198818057 100644
--- a/drivers/mtd/parsers/afs.c
+++ b/drivers/mtd/parsers/afs.c
@@ -68,6 +68,26 @@ static u32 word_sum(void *words, int num)
 	return sum;
 }
 
+static bool afs_is_v1(struct mtd_info *mtd, u_int off)
+{
+	/* The magic is 12 bytes from the end of the erase block */
+	u_int ptr = off + mtd->erasesize - 12;
+	u32 magic;
+	size_t sz;
+	int ret;
+
+	ret = mtd_read(mtd, ptr, 4, &sz, (u_char *)&magic);
+	if (ret < 0) {
+		printk(KERN_ERR "AFS: mtd read failed at 0x%x: %d\n",
+		       ptr, ret);
+		return false;
+	}
+	if (ret >= 0 && sz != 4)
+		return false;
+
+	return (magic == AFSV1_FOOTER_MAGIC);
+}
+
 static int
 afs_read_footer_v1(struct mtd_info *mtd, u_int *img_start, u_int *iis_start,
 		   u_int off, u_int mask)
@@ -176,18 +196,9 @@ static int parse_afs_partitions(struct mtd_info *mtd,
 	 */
 	mask = mtd->size - 1;
 
-	/*
-	 * First, calculate the size of the array we need for the
-	 * partition information.  We include in this the size of
-	 * the strings.
-	 */
+	/* Count the partitions by looping over all erase blocks */
 	for (i = off = sz = 0; off < mtd->size; off += mtd->erasesize) {
-		u_int iis_ptr, img_ptr;
-
-		ret = afs_read_footer_v1(mtd, &img_ptr, &iis_ptr, off, mask);
-		if (ret < 0)
-			return ret;
-		if (ret) {
+		if (afs_is_v1(mtd, off)) {
 			sz += sizeof(struct mtd_partition);
 			i += 1;
 		}
-- 
2.20.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/6] mtd: factor out v1 partition parsing
  2019-01-28 13:54 [PATCH 0/6] mtd: afs: Support AFSv2 parsing Linus Walleij
  2019-01-28 13:54 ` [PATCH 1/6] mtd: afs: simplify partition parsing Linus Walleij
  2019-01-28 13:54 ` [PATCH 2/6] mtd: afs: simplify partition detection Linus Walleij
@ 2019-01-28 13:54 ` Linus Walleij
  2019-01-28 13:54 ` [PATCH 4/6] mtd: afs: factor footer parsing into the v1 part parsing Linus Walleij
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Linus Walleij @ 2019-01-28 13:54 UTC (permalink / raw)
  To: David Woodhouse, Brian Norris, Boris Brezillon, Marek Vasut,
	Richard Weinberger, Cyrille Pitchen, linux-mtd
  Cc: Linus Walleij, Liviu Dudau, Ryan Harkin

This breaks out the parsing of v1 partitions so we can later add
a v2 partition parser.

Cc: Ryan Harkin <ryan.harkin@linaro.org>
Cc: Liviu Dudau <liviu.dudau@arm.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/mtd/parsers/afs.c | 88 ++++++++++++++++++++++-----------------
 1 file changed, 50 insertions(+), 38 deletions(-)

diff --git a/drivers/mtd/parsers/afs.c b/drivers/mtd/parsers/afs.c
index ccc198818057..32ded91ae66c 100644
--- a/drivers/mtd/parsers/afs.c
+++ b/drivers/mtd/parsers/afs.c
@@ -181,14 +181,18 @@ afs_read_iis_v1(struct mtd_info *mtd, struct image_info_v1 *iis, u_int ptr)
 	return ret;
 }
 
-static int parse_afs_partitions(struct mtd_info *mtd,
-				const struct mtd_partition **pparts,
-				struct mtd_part_parser_data *data)
+static int afs_parse_v1_partition(struct mtd_info *mtd,
+				  u_int off, struct mtd_partition *part)
 {
-	struct mtd_partition *parts;
-	u_int mask, off, sz;
-	int ret = 0;
-	int i;
+	struct image_info_v1 iis;
+	u_int mask;
+	/*
+	 * Static checks cannot see that we bail out if we have an error
+	 * reading the footer.
+	 */
+	u_int uninitialized_var(iis_ptr);
+	u_int uninitialized_var(img_ptr);
+	int ret;
 
 	/*
 	 * This is the address mask; we use this to mask off out of
@@ -196,6 +200,39 @@ static int parse_afs_partitions(struct mtd_info *mtd,
 	 */
 	mask = mtd->size - 1;
 
+	ret = afs_read_footer_v1(mtd, &img_ptr, &iis_ptr, off, mask);
+	if (ret < 0)
+		return ret;
+
+	/* Read the image info block */
+	ret = afs_read_iis_v1(mtd, &iis, iis_ptr);
+	if (ret < 0)
+		return ret;
+
+	part->name = kstrdup(iis.name, GFP_KERNEL);
+	if (!part->name)
+		return -ENOMEM;
+
+	part->size = (iis.length + mtd->erasesize - 1) & ~(mtd->erasesize - 1);
+	part->offset = img_ptr;
+	part->mask_flags = 0;
+
+	printk("  mtd: at 0x%08x, %5lluKiB, %8u, %s\n",
+	       img_ptr, part->size / 1024,
+	       iis.imageNumber, part->name);
+
+	return 0;
+}
+
+static int parse_afs_partitions(struct mtd_info *mtd,
+				const struct mtd_partition **pparts,
+				struct mtd_part_parser_data *data)
+{
+	struct mtd_partition *parts;
+	u_int off, sz;
+	int ret = 0;
+	int i;
+
 	/* Count the partitions by looping over all erase blocks */
 	for (i = off = sz = 0; off < mtd->size; off += mtd->erasesize) {
 		if (afs_is_v1(mtd, off)) {
@@ -215,38 +252,13 @@ static int parse_afs_partitions(struct mtd_info *mtd,
 	 * Identify the partitions
 	 */
 	for (i = off = 0; off < mtd->size; off += mtd->erasesize) {
-		struct image_info_v1 iis;
-		u_int iis_ptr, img_ptr;
-
-		/* Read the footer. */
-		ret = afs_read_footer_v1(mtd, &img_ptr, &iis_ptr, off, mask);
-		if (ret < 0)
-			goto out_free_parts;
-		if (ret == 0)
-			continue;
-
-		/* Read the image info block */
-		ret = afs_read_iis_v1(mtd, &iis, iis_ptr);
-		if (ret < 0)
-			goto out_free_parts;
-		if (ret == 0)
-			continue;
-
-		parts[i].name = kstrdup(iis.name, GFP_KERNEL);
-		if (!parts[i].name) {
-			ret = -ENOMEM;
-			goto out_free_parts;
-		}
 
-		parts[i].size		= (iis.length + mtd->erasesize - 1) & ~(mtd->erasesize - 1);
-		parts[i].offset	= img_ptr;
-		parts[i].mask_flags	= 0;
-
-		printk("  mtd%d: at 0x%08x, %5lluKiB, %8u, %s\n",
-			i, img_ptr, parts[i].size / 1024,
-			iis.imageNumber, parts[i].name);
-
-		i += 1;
+		if (afs_is_v1(mtd, off)) {
+			ret = afs_parse_v1_partition(mtd, off, &parts[i]);
+			if (ret)
+				goto out_free_parts;
+			i++;
+		}
 	}
 
 	*pparts = parts;
-- 
2.20.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 4/6] mtd: afs: factor footer parsing into the v1 part parsing
  2019-01-28 13:54 [PATCH 0/6] mtd: afs: Support AFSv2 parsing Linus Walleij
                   ` (2 preceding siblings ...)
  2019-01-28 13:54 ` [PATCH 3/6] mtd: factor out v1 partition parsing Linus Walleij
@ 2019-01-28 13:54 ` Linus Walleij
  2019-01-28 13:54 ` [PATCH 5/6] mtd: afs: factor the IIS read into partition parser Linus Walleij
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Linus Walleij @ 2019-01-28 13:54 UTC (permalink / raw)
  To: David Woodhouse, Brian Norris, Boris Brezillon, Marek Vasut,
	Richard Weinberger, Cyrille Pitchen, linux-mtd
  Cc: Linus Walleij, Liviu Dudau, Ryan Harkin

This simplifies the code by factoring in the image footer
parsing into the single function parsing the AFSv1 partitions.

Cc: Ryan Harkin <ryan.harkin@linaro.org>
Cc: Liviu Dudau <liviu.dudau@arm.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/mtd/parsers/afs.c | 98 ++++++++++++++++-----------------------
 1 file changed, 39 insertions(+), 59 deletions(-)

diff --git a/drivers/mtd/parsers/afs.c b/drivers/mtd/parsers/afs.c
index 32ded91ae66c..8ff82a548252 100644
--- a/drivers/mtd/parsers/afs.c
+++ b/drivers/mtd/parsers/afs.c
@@ -88,63 +88,6 @@ static bool afs_is_v1(struct mtd_info *mtd, u_int off)
 	return (magic == AFSV1_FOOTER_MAGIC);
 }
 
-static int
-afs_read_footer_v1(struct mtd_info *mtd, u_int *img_start, u_int *iis_start,
-		   u_int off, u_int mask)
-{
-	struct footer_v1 fs;
-	u_int ptr = off + mtd->erasesize - sizeof(fs);
-	size_t sz;
-	int ret;
-
-	ret = mtd_read(mtd, ptr, sizeof(fs), &sz, (u_char *)&fs);
-	if (ret >= 0 && sz != sizeof(fs))
-		ret = -EINVAL;
-
-	if (ret < 0) {
-		printk(KERN_ERR "AFS: mtd read failed at 0x%x: %d\n",
-			ptr, ret);
-		return ret;
-	}
-
-	/*
-	 * Does it contain the magic number?
-	 */
-	if (fs.signature != AFSV1_FOOTER_MAGIC)
-		return 0;
-
-	/*
-	 * Check the checksum.
-	 */
-	if (word_sum(&fs, sizeof(fs) / sizeof(u32)) != 0xffffffff)
-		return 0;
-
-	/*
-	 * Don't touch the SIB.
-	 */
-	if (fs.type == 2)
-		return 0;
-
-	*iis_start = fs.image_info_base & mask;
-	*img_start = fs.image_start & mask;
-
-	/*
-	 * Check the image info base.  This can not
-	 * be located after the footer structure.
-	 */
-	if (*iis_start >= ptr)
-		return 0;
-
-	/*
-	 * Check the start of this image.  The image
-	 * data can not be located after this block.
-	 */
-	if (*img_start > off)
-		return 0;
-
-	return 1;
-}
-
 static int
 afs_read_iis_v1(struct mtd_info *mtd, struct image_info_v1 *iis, u_int ptr)
 {
@@ -184,6 +127,7 @@ afs_read_iis_v1(struct mtd_info *mtd, struct image_info_v1 *iis, u_int ptr)
 static int afs_parse_v1_partition(struct mtd_info *mtd,
 				  u_int off, struct mtd_partition *part)
 {
+	struct footer_v1 fs;
 	struct image_info_v1 iis;
 	u_int mask;
 	/*
@@ -192,6 +136,8 @@ static int afs_parse_v1_partition(struct mtd_info *mtd,
 	 */
 	u_int uninitialized_var(iis_ptr);
 	u_int uninitialized_var(img_ptr);
+	u_int ptr;
+	size_t sz;
 	int ret;
 
 	/*
@@ -200,9 +146,43 @@ static int afs_parse_v1_partition(struct mtd_info *mtd,
 	 */
 	mask = mtd->size - 1;
 
-	ret = afs_read_footer_v1(mtd, &img_ptr, &iis_ptr, off, mask);
-	if (ret < 0)
+	ptr = off + mtd->erasesize - sizeof(fs);
+	ret = mtd_read(mtd, ptr, sizeof(fs), &sz, (u_char *)&fs);
+	if (ret >= 0 && sz != sizeof(fs))
+		ret = -EINVAL;
+	if (ret < 0) {
+		printk(KERN_ERR "AFS: mtd read failed at 0x%x: %d\n",
+		       ptr, ret);
 		return ret;
+	}
+	/*
+	 * Check the checksum.
+	 */
+	if (word_sum(&fs, sizeof(fs) / sizeof(u32)) != 0xffffffff)
+		return -EINVAL;
+
+	/*
+	 * Hide the SIB (System Information Block)
+	 */
+	if (fs.type == 2)
+		return 0;
+
+	iis_ptr = fs.image_info_base & mask;
+	img_ptr = fs.image_start & mask;
+
+	/*
+	 * Check the image info base.  This can not
+	 * be located after the footer structure.
+	 */
+	if (iis_ptr >= ptr)
+		return 0;
+
+	/*
+	 * Check the start of this image.  The image
+	 * data can not be located after this block.
+	 */
+	if (img_ptr > off)
+		return 0;
 
 	/* Read the image info block */
 	ret = afs_read_iis_v1(mtd, &iis, iis_ptr);
-- 
2.20.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 5/6] mtd: afs: factor the IIS read into partition parser
  2019-01-28 13:54 [PATCH 0/6] mtd: afs: Support AFSv2 parsing Linus Walleij
                   ` (3 preceding siblings ...)
  2019-01-28 13:54 ` [PATCH 4/6] mtd: afs: factor footer parsing into the v1 part parsing Linus Walleij
@ 2019-01-28 13:54 ` Linus Walleij
  2019-01-28 13:54 ` [PATCH 6/6] mtd: afs: add v2 partition parsing Linus Walleij
  2019-04-28 11:38 ` [PATCH 0/6] mtd: afs: Support AFSv2 parsing Linus Walleij
  6 siblings, 0 replies; 12+ messages in thread
From: Linus Walleij @ 2019-01-28 13:54 UTC (permalink / raw)
  To: David Woodhouse, Brian Norris, Boris Brezillon, Marek Vasut,
	Richard Weinberger, Cyrille Pitchen, linux-mtd
  Cc: Linus Walleij, Liviu Dudau, Ryan Harkin

Factor the IIS (Image Information Structure) reading into the
partition parser, giving us a single, clean partition parser
function.

Cc: Ryan Harkin <ryan.harkin@linaro.org>
Cc: Liviu Dudau <liviu.dudau@arm.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/mtd/parsers/afs.c | 59 +++++++++++++--------------------------
 1 file changed, 20 insertions(+), 39 deletions(-)

diff --git a/drivers/mtd/parsers/afs.c b/drivers/mtd/parsers/afs.c
index 8ff82a548252..72c688b8a383 100644
--- a/drivers/mtd/parsers/afs.c
+++ b/drivers/mtd/parsers/afs.c
@@ -88,42 +88,6 @@ static bool afs_is_v1(struct mtd_info *mtd, u_int off)
 	return (magic == AFSV1_FOOTER_MAGIC);
 }
 
-static int
-afs_read_iis_v1(struct mtd_info *mtd, struct image_info_v1 *iis, u_int ptr)
-{
-	size_t sz;
-	int ret, i;
-
-	memset(iis, 0, sizeof(*iis));
-	ret = mtd_read(mtd, ptr, sizeof(*iis), &sz, (u_char *)iis);
-	if (ret < 0)
-		goto failed;
-
-	if (sz != sizeof(*iis)) {
-		ret = -EINVAL;
-		goto failed;
-	}
-
-	ret = 0;
-
-	/*
-	 * Validate the name - it must be NUL terminated.
-	 */
-	for (i = 0; i < sizeof(iis->name); i++)
-		if (iis->name[i] == '\0')
-			break;
-
-	if (i < sizeof(iis->name))
-		ret = 1;
-
-	return ret;
-
- failed:
-	printk(KERN_ERR "AFS: mtd read failed at 0x%x: %d\n",
-		ptr, ret);
-	return ret;
-}
-
 static int afs_parse_v1_partition(struct mtd_info *mtd,
 				  u_int off, struct mtd_partition *part)
 {
@@ -139,6 +103,7 @@ static int afs_parse_v1_partition(struct mtd_info *mtd,
 	u_int ptr;
 	size_t sz;
 	int ret;
+	int i;
 
 	/*
 	 * This is the address mask; we use this to mask off out of
@@ -185,9 +150,25 @@ static int afs_parse_v1_partition(struct mtd_info *mtd,
 		return 0;
 
 	/* Read the image info block */
-	ret = afs_read_iis_v1(mtd, &iis, iis_ptr);
-	if (ret < 0)
-		return ret;
+	memset(&iis, 0, sizeof(iis));
+	ret = mtd_read(mtd, iis_ptr, sizeof(iis), &sz, (u_char *)&iis);
+	if (ret < 0) {
+		printk(KERN_ERR "AFS: mtd read failed at 0x%x: %d\n",
+		       iis_ptr, ret);
+		return -EINVAL;
+	}
+
+	if (sz != sizeof(iis))
+		return -EINVAL;
+
+	/*
+	 * Validate the name - it must be NUL terminated.
+	 */
+	for (i = 0; i < sizeof(iis.name); i++)
+		if (iis.name[i] == '\0')
+			break;
+	if (i > sizeof(iis.name))
+		return -EINVAL;
 
 	part->name = kstrdup(iis.name, GFP_KERNEL);
 	if (!part->name)
-- 
2.20.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 6/6] mtd: afs: add v2 partition parsing
  2019-01-28 13:54 [PATCH 0/6] mtd: afs: Support AFSv2 parsing Linus Walleij
                   ` (4 preceding siblings ...)
  2019-01-28 13:54 ` [PATCH 5/6] mtd: afs: factor the IIS read into partition parser Linus Walleij
@ 2019-01-28 13:54 ` Linus Walleij
  2019-04-28 11:38 ` [PATCH 0/6] mtd: afs: Support AFSv2 parsing Linus Walleij
  6 siblings, 0 replies; 12+ messages in thread
From: Linus Walleij @ 2019-01-28 13:54 UTC (permalink / raw)
  To: David Woodhouse, Brian Norris, Boris Brezillon, Marek Vasut,
	Richard Weinberger, Cyrille Pitchen, linux-mtd
  Cc: Linus Walleij, Liviu Dudau, Ryan Harkin

The AFS v2 partition type appear in later ARM reference designs
such as RealView, Versatile Express and the 64bit Juno Development
Platform.

The image informations is padded with a 32bit word (4 bytes) on
the 32bit platforms and a 64bit word (8 bytes) on the 64bit
platforms. The boot monitor source code gives at hand that this
is because the first entry in the struct mapped over the image
information is a "next" pointer for a linked list, filled in
by firmware after reading in the info block, and always zero
in the flash. We adjust padding by checking what padding gives
the right checksum.

This was tested on:
- Integrator/AP (v1 partitions)
- RealView PB11MPCore (v2 32bit partitions)
- Juno Development System (v2 64bit partitions)

All systems display the images in flash very nicely as separate
partitions, e.g on Juno:

4 afs partitions found on MTD device 8000000.flash
Creating 4 MTD partitions on "8000000.flash":
0x000000040000-0x0000000c0000 : "fip"
0x000000ec0000-0x0000018c0000 : "Image"
0x000000f00000-0x000000f40000 : "juno"
0x000003ec0000-0x000003f00000 : "bl1"

Cc: Ryan Harkin <ryan.harkin@linaro.org>
Cc: Liviu Dudau <liviu.dudau@arm.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/mtd/parsers/afs.c | 158 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 157 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/parsers/afs.c b/drivers/mtd/parsers/afs.c
index 72c688b8a383..0c730024f806 100644
--- a/drivers/mtd/parsers/afs.c
+++ b/drivers/mtd/parsers/afs.c
@@ -3,6 +3,7 @@
     drivers/mtd/afs.c: ARM Flash Layout/Partitioning
 
     Copyright © 2000 ARM Limited
+    Copyright (C) 2019 Linus Walleij
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -35,6 +36,8 @@
 #include <linux/mtd/partitions.h>
 
 #define AFSV1_FOOTER_MAGIC 0xA0FFFF9F
+#define AFSV2_FOOTER_MAGIC1 0x464C5348 /* "FLSH" */
+#define AFSV2_FOOTER_MAGIC2 0x464F4F54 /* "FOOT" */
 
 struct footer_v1 {
 	u32 image_info_base;	/* Address of first word of ImageFooter  */
@@ -68,6 +71,22 @@ static u32 word_sum(void *words, int num)
 	return sum;
 }
 
+static u32 word_sum_v2(u32 *p, u32 num)
+{
+	u32 sum = 0;
+	int i;
+
+	for (i = 0; i < num; i++) {
+		u32 val;
+
+		val = p[i];
+		if (val > ~sum)
+			sum++;
+		sum += val;
+	}
+	return ~sum;
+}
+
 static bool afs_is_v1(struct mtd_info *mtd, u_int off)
 {
 	/* The magic is 12 bytes from the end of the erase block */
@@ -88,6 +107,27 @@ static bool afs_is_v1(struct mtd_info *mtd, u_int off)
 	return (magic == AFSV1_FOOTER_MAGIC);
 }
 
+static bool afs_is_v2(struct mtd_info *mtd, u_int off)
+{
+	/* The magic is the 8 last bytes of the erase block */
+	u_int ptr = off + mtd->erasesize - 8;
+	u32 foot[2];
+	size_t sz;
+	int ret;
+
+	ret = mtd_read(mtd, ptr, 8, &sz, (u_char *)foot);
+	if (ret < 0) {
+		printk(KERN_ERR "AFS: mtd read failed at 0x%x: %d\n",
+		       ptr, ret);
+		return false;
+	}
+	if (ret >= 0 && sz != 8)
+		return false;
+
+	return (foot[0] == AFSV2_FOOTER_MAGIC1 &&
+		foot[1] == AFSV2_FOOTER_MAGIC2);
+}
+
 static int afs_parse_v1_partition(struct mtd_info *mtd,
 				  u_int off, struct mtd_partition *part)
 {
@@ -185,6 +225,113 @@ static int afs_parse_v1_partition(struct mtd_info *mtd,
 	return 0;
 }
 
+static int afs_parse_v2_partition(struct mtd_info *mtd,
+				  u_int off, struct mtd_partition *part)
+{
+	u_int ptr;
+	u32 footer[12];
+	u32 imginfo[36];
+	char *name;
+	u32 version;
+	u32 entrypoint;
+	u32 attributes;
+	u32 region_count;
+	u32 block_start;
+	u32 block_end;
+	u32 crc;
+	size_t sz;
+	int ret;
+	int i;
+	int pad = 0;
+
+	pr_debug("Parsing v2 partition @%08x-%08x\n",
+		 off, off + mtd->erasesize);
+
+	/* First read the footer */
+	ptr = off + mtd->erasesize - sizeof(footer);
+	ret = mtd_read(mtd, ptr, sizeof(footer), &sz, (u_char *)footer);
+	if ((ret < 0) || (ret >= 0 && sz != sizeof(footer))) {
+		pr_err("AFS: mtd read failed at 0x%x: %d\n",
+		       ptr, ret);
+		return -EIO;
+	}
+	name = (char *) &footer[0];
+	version = footer[9];
+	ptr = off + mtd->erasesize - sizeof(footer) - footer[8];
+
+	pr_debug("found image \"%s\", version %08x, info @%08x\n",
+		 name, version, ptr);
+
+	/* Then read the image information */
+	ret = mtd_read(mtd, ptr, sizeof(imginfo), &sz, (u_char *)imginfo);
+	if ((ret < 0) || (ret >= 0 && sz != sizeof(imginfo))) {
+		pr_err("AFS: mtd read failed at 0x%x: %d\n",
+		       ptr, ret);
+		return -EIO;
+	}
+
+	/* 32bit platforms have 4 bytes padding */
+	crc = word_sum_v2(&imginfo[1], 34);
+	if (!crc) {
+		pr_debug("Padding 1 word (4 bytes)\n");
+		pad = 1;
+	} else {
+		/* 64bit platforms have 8 bytes padding */
+		crc = word_sum_v2(&imginfo[2], 34);
+		if (!crc) {
+			pr_debug("Padding 2 words (8 bytes)\n");
+			pad = 2;
+		}
+	}
+	if (crc) {
+		pr_err("AFS: bad checksum on v2 image info: %08x\n", crc);
+		return -EINVAL;
+	}
+	entrypoint = imginfo[pad];
+	attributes = imginfo[pad+1];
+	region_count = imginfo[pad+2];
+	block_start = imginfo[20];
+	block_end = imginfo[21];
+
+	pr_debug("image entry=%08x, attr=%08x, regions=%08x, "
+		 "bs=%08x, be=%08x\n",
+		 entrypoint, attributes, region_count,
+		 block_start, block_end);
+
+	for (i = 0; i < region_count; i++) {
+		u32 region_load_addr = imginfo[pad + 3 + i*4];
+		u32 region_size = imginfo[pad + 4 + i*4];
+		u32 region_offset = imginfo[pad + 5 + i*4];
+		u32 region_start;
+		u32 region_end;
+
+		pr_debug("  region %d: address: %08x, size: %08x, "
+			 "offset: %08x\n",
+			 i,
+			 region_load_addr,
+			 region_size,
+			 region_offset);
+
+		region_start = off + region_offset;
+		region_end = region_start + region_size;
+		/* Align partition to end of erase block */
+		region_end += (mtd->erasesize - 1);
+		region_end &= ~(mtd->erasesize -1);
+		pr_debug("   partition start = %08x, partition end = %08x\n",
+			 region_start, region_end);
+
+		/* Create one partition per region */
+		part->name = kstrdup(name, GFP_KERNEL);
+		if (!part->name)
+			return -ENOMEM;
+		part->offset = region_start;
+		part->size = region_end - region_start;
+		part->mask_flags = 0;
+	}
+
+	return 0;
+}
+
 static int parse_afs_partitions(struct mtd_info *mtd,
 				const struct mtd_partition **pparts,
 				struct mtd_part_parser_data *data)
@@ -200,6 +347,10 @@ static int parse_afs_partitions(struct mtd_info *mtd,
 			sz += sizeof(struct mtd_partition);
 			i += 1;
 		}
+		if (afs_is_v2(mtd, off)) {
+			sz += sizeof(struct mtd_partition);
+			i += 1;
+		}
 	}
 
 	if (!i)
@@ -213,13 +364,18 @@ static int parse_afs_partitions(struct mtd_info *mtd,
 	 * Identify the partitions
 	 */
 	for (i = off = 0; off < mtd->size; off += mtd->erasesize) {
-
 		if (afs_is_v1(mtd, off)) {
 			ret = afs_parse_v1_partition(mtd, off, &parts[i]);
 			if (ret)
 				goto out_free_parts;
 			i++;
 		}
+		if (afs_is_v2(mtd, off)) {
+			ret = afs_parse_v2_partition(mtd, off, &parts[i]);
+			if (ret)
+				goto out_free_parts;
+			i++;
+		}
 	}
 
 	*pparts = parts;
-- 
2.20.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/6] mtd: afs: simplify partition parsing
  2019-01-28 13:54 ` [PATCH 1/6] mtd: afs: simplify partition parsing Linus Walleij
@ 2019-01-31 17:13   ` Liviu Dudau
  2019-01-31 17:45     ` Boris Brezillon
  2019-02-12 14:31   ` Liviu Dudau
  1 sibling, 1 reply; 12+ messages in thread
From: Liviu Dudau @ 2019-01-31 17:13 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Boris Brezillon, Richard Weinberger, Marek Vasut, Ryan Harkin,
	linux-mtd, Cyrille Pitchen, Brian Norris, David Woodhouse

Hi Linus,

On Mon, Jan 28, 2019 at 02:54:44PM +0100, Linus Walleij wrote:
> This simplifies the AFS partition parsing to make the code
> more straight-forward and readable.
> 
> Before this patch the code tried to calculate the memory required
> to hold the partition info by adding up the sizes of the strings
> of the names and adding that to a single memory allocation,
> indexing the name pointers in front of the struct mtd_partition
> allocations so all allocated data was in one chunk.
> 
> This is overzealous. Instead use kstrdup and bail out,
> kfree():ing the memory used for MTD partitions and names alike
> on the errorpath.
> 
> In the process rename the index variable from idx to i.
> 
> Cc: Ryan Harkin <ryan.harkin@linaro.org>
> Cc: Liviu Dudau <liviu.dudau@arm.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  drivers/mtd/parsers/afs.c | 67 +++++++++++++++++++--------------------

What kernel is this series based on? Current Torvalds' tree has the
afs.c file in drivers/mtd and not in drivers/mtd/parsers/. Is there a
patch that I'm missing moving things around?

Best regards,
Liviu

>  1 file changed, 32 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/mtd/parsers/afs.c b/drivers/mtd/parsers/afs.c
> index 3679e1d22595..c489938cd665 100644
> --- a/drivers/mtd/parsers/afs.c
> +++ b/drivers/mtd/parsers/afs.c
> @@ -166,9 +166,9 @@ static int parse_afs_partitions(struct mtd_info *mtd,
>  				struct mtd_part_parser_data *data)
>  {
>  	struct mtd_partition *parts;
> -	u_int mask, off, idx, sz;
> +	u_int mask, off, sz;
>  	int ret = 0;
> -	char *str;
> +	int i;
>  
>  	/*
>  	 * This is the address mask; we use this to mask off out of
> @@ -181,78 +181,75 @@ static int parse_afs_partitions(struct mtd_info *mtd,
>  	 * partition information.  We include in this the size of
>  	 * the strings.
>  	 */
> -	for (idx = off = sz = 0; off < mtd->size; off += mtd->erasesize) {
> -		struct image_info_v1 iis;
> +	for (i = off = sz = 0; off < mtd->size; off += mtd->erasesize) {
>  		u_int iis_ptr, img_ptr;
>  
>  		ret = afs_read_footer_v1(mtd, &img_ptr, &iis_ptr, off, mask);
>  		if (ret < 0)
> -			break;
> +			return ret;
>  		if (ret) {
> -			ret = afs_read_iis_v1(mtd, &iis, iis_ptr);
> -			if (ret < 0)
> -				break;
> -			if (ret == 0)
> -				continue;
> -
>  			sz += sizeof(struct mtd_partition);
> -			sz += strlen(iis.name) + 1;
> -			idx += 1;
> +			i += 1;
>  		}
>  	}
>  
> -	if (!sz)
> -		return ret;
> +	if (!i)
> +		return 0;
>  
>  	parts = kzalloc(sz, GFP_KERNEL);
>  	if (!parts)
>  		return -ENOMEM;
>  
> -	str = (char *)(parts + idx);
> -
>  	/*
>  	 * Identify the partitions
>  	 */
> -	for (idx = off = 0; off < mtd->size; off += mtd->erasesize) {
> +	for (i = off = 0; off < mtd->size; off += mtd->erasesize) {
>  		struct image_info_v1 iis;
>  		u_int iis_ptr, img_ptr;
>  
>  		/* Read the footer. */
>  		ret = afs_read_footer_v1(mtd, &img_ptr, &iis_ptr, off, mask);
>  		if (ret < 0)
> -			break;
> +			goto out_free_parts;
>  		if (ret == 0)
>  			continue;
>  
>  		/* Read the image info block */
>  		ret = afs_read_iis_v1(mtd, &iis, iis_ptr);
>  		if (ret < 0)
> -			break;
> +			goto out_free_parts;
>  		if (ret == 0)
>  			continue;
>  
> -		strcpy(str, iis.name);
> +		parts[i].name = kstrdup(iis.name, GFP_KERNEL);
> +		if (!parts[i].name) {
> +			ret = -ENOMEM;
> +			goto out_free_parts;
> +		}
>  
> -		parts[idx].name		= str;
> -		parts[idx].size		= (iis.length + mtd->erasesize - 1) & ~(mtd->erasesize - 1);
> -		parts[idx].offset	= img_ptr;
> -		parts[idx].mask_flags	= 0;
> +		parts[i].size		= (iis.length + mtd->erasesize - 1) & ~(mtd->erasesize - 1);
> +		parts[i].offset	= img_ptr;
> +		parts[i].mask_flags	= 0;
>  
>  		printk("  mtd%d: at 0x%08x, %5lluKiB, %8u, %s\n",
> -			idx, img_ptr, parts[idx].size / 1024,
> -			iis.imageNumber, str);
> -
> -		idx += 1;
> -		str = str + strlen(iis.name) + 1;
> -	}
> +			i, img_ptr, parts[i].size / 1024,
> +			iis.imageNumber, parts[i].name);
>  
> -	if (!idx) {
> -		kfree(parts);
> -		parts = NULL;
> +		i += 1;
>  	}
>  
>  	*pparts = parts;
> -	return idx ? idx : ret;
> +	return i;
> +
> +out_free_parts:
> +	while (i >= 0) {
> +		if (parts[i].name)
> +			kfree(parts[i].name);
> +		i--;
> +	}
> +	kfree(parts);
> +	*pparts = NULL;
> +	return ret;
>  }
>  
>  static const struct of_device_id mtd_parser_afs_of_match_table[] = {
> -- 
> 2.20.1
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ¯\_(ツ)_/¯

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/6] mtd: afs: simplify partition parsing
  2019-01-31 17:13   ` Liviu Dudau
@ 2019-01-31 17:45     ` Boris Brezillon
  2019-02-05 11:25       ` Liviu Dudau
  0 siblings, 1 reply; 12+ messages in thread
From: Boris Brezillon @ 2019-01-31 17:45 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: Boris Brezillon, Richard Weinberger, Linus Walleij, Marek Vasut,
	Ryan Harkin, linux-mtd, Cyrille Pitchen, Brian Norris,
	David Woodhouse

Hi Liviu,

On Thu, 31 Jan 2019 17:13:27 +0000
Liviu Dudau <liviu.dudau@arm.com> wrote:

> Hi Linus,
> 
> On Mon, Jan 28, 2019 at 02:54:44PM +0100, Linus Walleij wrote:
> > This simplifies the AFS partition parsing to make the code
> > more straight-forward and readable.
> > 
> > Before this patch the code tried to calculate the memory required
> > to hold the partition info by adding up the sizes of the strings
> > of the names and adding that to a single memory allocation,
> > indexing the name pointers in front of the struct mtd_partition
> > allocations so all allocated data was in one chunk.
> > 
> > This is overzealous. Instead use kstrdup and bail out,
> > kfree():ing the memory used for MTD partitions and names alike
> > on the errorpath.
> > 
> > In the process rename the index variable from idx to i.
> > 
> > Cc: Ryan Harkin <ryan.harkin@linaro.org>
> > Cc: Liviu Dudau <liviu.dudau@arm.com>
> > Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> > ---
> >  drivers/mtd/parsers/afs.c | 67 +++++++++++++++++++--------------------  
> 
> What kernel is this series based on? Current Torvalds' tree has the
> afs.c file in drivers/mtd and not in drivers/mtd/parsers/. Is there a
> patch that I'm missing moving things around?

It depends on this series [1] (mentioned in the cover letter).

Regards,

Boris

[1]http://patchwork.ozlabs.org/project/linux-mtd/list/?series=87760

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/6] mtd: afs: simplify partition parsing
  2019-01-31 17:45     ` Boris Brezillon
@ 2019-02-05 11:25       ` Liviu Dudau
  0 siblings, 0 replies; 12+ messages in thread
From: Liviu Dudau @ 2019-02-05 11:25 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Boris Brezillon, Richard Weinberger, Linus Walleij, Marek Vasut,
	Ryan Harkin, linux-mtd, Cyrille Pitchen, Brian Norris,
	David Woodhouse

On Thu, Jan 31, 2019 at 06:45:03PM +0100, Boris Brezillon wrote:
> Hi Liviu,
> 
> On Thu, 31 Jan 2019 17:13:27 +0000
> Liviu Dudau <liviu.dudau@arm.com> wrote:
> 
> > Hi Linus,
> > 
> > On Mon, Jan 28, 2019 at 02:54:44PM +0100, Linus Walleij wrote:
> > > This simplifies the AFS partition parsing to make the code
> > > more straight-forward and readable.
> > > 
> > > Before this patch the code tried to calculate the memory required
> > > to hold the partition info by adding up the sizes of the strings
> > > of the names and adding that to a single memory allocation,
> > > indexing the name pointers in front of the struct mtd_partition
> > > allocations so all allocated data was in one chunk.
> > > 
> > > This is overzealous. Instead use kstrdup and bail out,
> > > kfree():ing the memory used for MTD partitions and names alike
> > > on the errorpath.
> > > 
> > > In the process rename the index variable from idx to i.
> > > 
> > > Cc: Ryan Harkin <ryan.harkin@linaro.org>
> > > Cc: Liviu Dudau <liviu.dudau@arm.com>
> > > Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> > > ---
> > >  drivers/mtd/parsers/afs.c | 67 +++++++++++++++++++--------------------  
> > 
> > What kernel is this series based on? Current Torvalds' tree has the
> > afs.c file in drivers/mtd and not in drivers/mtd/parsers/. Is there a
> > patch that I'm missing moving things around?
> 
> It depends on this series [1] (mentioned in the cover letter).

Funny that, but the cover letter was missing from the series I've
received :)

Thanks for the info!

Best regards,
Liviu

> 
> Regards,
> 
> Boris
> 
> [1]http://patchwork.ozlabs.org/project/linux-mtd/list/?series=87760

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ¯\_(ツ)_/¯

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/6] mtd: afs: simplify partition parsing
  2019-01-28 13:54 ` [PATCH 1/6] mtd: afs: simplify partition parsing Linus Walleij
  2019-01-31 17:13   ` Liviu Dudau
@ 2019-02-12 14:31   ` Liviu Dudau
  1 sibling, 0 replies; 12+ messages in thread
From: Liviu Dudau @ 2019-02-12 14:31 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Boris Brezillon, Richard Weinberger, Marek Vasut, Ryan Harkin,
	linux-mtd, Cyrille Pitchen, Brian Norris, David Woodhouse

On Mon, Jan 28, 2019 at 02:54:44PM +0100, Linus Walleij wrote:
> This simplifies the AFS partition parsing to make the code
> more straight-forward and readable.
> 
> Before this patch the code tried to calculate the memory required
> to hold the partition info by adding up the sizes of the strings
> of the names and adding that to a single memory allocation,
> indexing the name pointers in front of the struct mtd_partition
> allocations so all allocated data was in one chunk.
> 
> This is overzealous. Instead use kstrdup and bail out,
> kfree():ing the memory used for MTD partitions and names alike
> on the errorpath.
> 
> In the process rename the index variable from idx to i.
> 
> Cc: Ryan Harkin <ryan.harkin@linaro.org>
> Cc: Liviu Dudau <liviu.dudau@arm.com>

For the whole series:

Acked-by: Liviu Dudau <liviu.dudau@arm.com>

Best regards,
Liviu

> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  drivers/mtd/parsers/afs.c | 67 +++++++++++++++++++--------------------
>  1 file changed, 32 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/mtd/parsers/afs.c b/drivers/mtd/parsers/afs.c
> index 3679e1d22595..c489938cd665 100644
> --- a/drivers/mtd/parsers/afs.c
> +++ b/drivers/mtd/parsers/afs.c
> @@ -166,9 +166,9 @@ static int parse_afs_partitions(struct mtd_info *mtd,
>  				struct mtd_part_parser_data *data)
>  {
>  	struct mtd_partition *parts;
> -	u_int mask, off, idx, sz;
> +	u_int mask, off, sz;
>  	int ret = 0;
> -	char *str;
> +	int i;
>  
>  	/*
>  	 * This is the address mask; we use this to mask off out of
> @@ -181,78 +181,75 @@ static int parse_afs_partitions(struct mtd_info *mtd,
>  	 * partition information.  We include in this the size of
>  	 * the strings.
>  	 */
> -	for (idx = off = sz = 0; off < mtd->size; off += mtd->erasesize) {
> -		struct image_info_v1 iis;
> +	for (i = off = sz = 0; off < mtd->size; off += mtd->erasesize) {
>  		u_int iis_ptr, img_ptr;
>  
>  		ret = afs_read_footer_v1(mtd, &img_ptr, &iis_ptr, off, mask);
>  		if (ret < 0)
> -			break;
> +			return ret;
>  		if (ret) {
> -			ret = afs_read_iis_v1(mtd, &iis, iis_ptr);
> -			if (ret < 0)
> -				break;
> -			if (ret == 0)
> -				continue;
> -
>  			sz += sizeof(struct mtd_partition);
> -			sz += strlen(iis.name) + 1;
> -			idx += 1;
> +			i += 1;
>  		}
>  	}
>  
> -	if (!sz)
> -		return ret;
> +	if (!i)
> +		return 0;
>  
>  	parts = kzalloc(sz, GFP_KERNEL);
>  	if (!parts)
>  		return -ENOMEM;
>  
> -	str = (char *)(parts + idx);
> -
>  	/*
>  	 * Identify the partitions
>  	 */
> -	for (idx = off = 0; off < mtd->size; off += mtd->erasesize) {
> +	for (i = off = 0; off < mtd->size; off += mtd->erasesize) {
>  		struct image_info_v1 iis;
>  		u_int iis_ptr, img_ptr;
>  
>  		/* Read the footer. */
>  		ret = afs_read_footer_v1(mtd, &img_ptr, &iis_ptr, off, mask);
>  		if (ret < 0)
> -			break;
> +			goto out_free_parts;
>  		if (ret == 0)
>  			continue;
>  
>  		/* Read the image info block */
>  		ret = afs_read_iis_v1(mtd, &iis, iis_ptr);
>  		if (ret < 0)
> -			break;
> +			goto out_free_parts;
>  		if (ret == 0)
>  			continue;
>  
> -		strcpy(str, iis.name);
> +		parts[i].name = kstrdup(iis.name, GFP_KERNEL);
> +		if (!parts[i].name) {
> +			ret = -ENOMEM;
> +			goto out_free_parts;
> +		}
>  
> -		parts[idx].name		= str;
> -		parts[idx].size		= (iis.length + mtd->erasesize - 1) & ~(mtd->erasesize - 1);
> -		parts[idx].offset	= img_ptr;
> -		parts[idx].mask_flags	= 0;
> +		parts[i].size		= (iis.length + mtd->erasesize - 1) & ~(mtd->erasesize - 1);
> +		parts[i].offset	= img_ptr;
> +		parts[i].mask_flags	= 0;
>  
>  		printk("  mtd%d: at 0x%08x, %5lluKiB, %8u, %s\n",
> -			idx, img_ptr, parts[idx].size / 1024,
> -			iis.imageNumber, str);
> -
> -		idx += 1;
> -		str = str + strlen(iis.name) + 1;
> -	}
> +			i, img_ptr, parts[i].size / 1024,
> +			iis.imageNumber, parts[i].name);
>  
> -	if (!idx) {
> -		kfree(parts);
> -		parts = NULL;
> +		i += 1;
>  	}
>  
>  	*pparts = parts;
> -	return idx ? idx : ret;
> +	return i;
> +
> +out_free_parts:
> +	while (i >= 0) {
> +		if (parts[i].name)
> +			kfree(parts[i].name);
> +		i--;
> +	}
> +	kfree(parts);
> +	*pparts = NULL;
> +	return ret;
>  }
>  
>  static const struct of_device_id mtd_parser_afs_of_match_table[] = {
> -- 
> 2.20.1
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ¯\_(ツ)_/¯

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 0/6] mtd: afs: Support AFSv2 parsing
  2019-01-28 13:54 [PATCH 0/6] mtd: afs: Support AFSv2 parsing Linus Walleij
                   ` (5 preceding siblings ...)
  2019-01-28 13:54 ` [PATCH 6/6] mtd: afs: add v2 partition parsing Linus Walleij
@ 2019-04-28 11:38 ` Linus Walleij
  6 siblings, 0 replies; 12+ messages in thread
From: Linus Walleij @ 2019-04-28 11:38 UTC (permalink / raw)
  To: David Woodhouse, Brian Norris, Boris Brezillon, Marek Vasut,
	Richard Weinberger, Cyrille Pitchen, linux-mtd

On Mon, Jan 28, 2019 at 2:54 PM Linus Walleij <linus.walleij@linaro.org> wrote:

> The later versions of the ARM reference designs use
> AFSv2 with a new type of firmware header than in the
> v1 version found in earlier versions.
>
> Extend the AFS partition parser to suppoer AFSv2.

Ping on this patch set.

I recognize something must be holding application back
as I actually submitted this for v5.0, and then resent this
for v5.1 and it doesn't seem to be getting applied.

Is there anything I can do to help?

If I get an ACK from one of the maintainers I can
ask the ARM SoC people to pull it in instead.

Yours,
Linus Walleij

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2019-04-28 11:39 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-28 13:54 [PATCH 0/6] mtd: afs: Support AFSv2 parsing Linus Walleij
2019-01-28 13:54 ` [PATCH 1/6] mtd: afs: simplify partition parsing Linus Walleij
2019-01-31 17:13   ` Liviu Dudau
2019-01-31 17:45     ` Boris Brezillon
2019-02-05 11:25       ` Liviu Dudau
2019-02-12 14:31   ` Liviu Dudau
2019-01-28 13:54 ` [PATCH 2/6] mtd: afs: simplify partition detection Linus Walleij
2019-01-28 13:54 ` [PATCH 3/6] mtd: factor out v1 partition parsing Linus Walleij
2019-01-28 13:54 ` [PATCH 4/6] mtd: afs: factor footer parsing into the v1 part parsing Linus Walleij
2019-01-28 13:54 ` [PATCH 5/6] mtd: afs: factor the IIS read into partition parser Linus Walleij
2019-01-28 13:54 ` [PATCH 6/6] mtd: afs: add v2 partition parsing Linus Walleij
2019-04-28 11:38 ` [PATCH 0/6] mtd: afs: Support AFSv2 parsing Linus Walleij

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).