[PATCH 1/2] fip: Store image data in single buffer

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Right now in fip_parse() we read the whole FIP image into an allocated
buffer, then allocate buffers for the different blobs contained in the
FIP image and memcpy the blobs there from the full buffer. Let's
optimize this a bit by keeping the full buffer. Instead of allocating
separate buffers for the blobs, just put pointers to the full buffers
into struct fip_image and set the buf_no_free flag indicating that they
should not be freed.

Signed-off-by: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx>
---
 lib/fip.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/lib/fip.c b/lib/fip.c
index 39b0fd20aa..806f172318 100644
--- a/lib/fip.c
+++ b/lib/fip.c
@@ -160,12 +160,15 @@ int fip_parse(struct fip_state *fip,
 {
 	struct stat st;
 	int fd;
-	char *buf, *bufend;
+	char *bufend;
 	fip_toc_header_t *toc_header;
 	fip_toc_entry_t *toc_entry;
 	int terminated = 0;
 	size_t st_size;
 
+	if (fip->buffer)
+		return -EBUSY;
+
 	fd = open(filename, O_RDONLY);
 	if (fd < 0) {
 		pr_err("open %s: %m\n", filename);
@@ -179,13 +182,13 @@ int fip_parse(struct fip_state *fip,
 
 	st_size = st.st_size;
 
-	buf = xmalloc(st_size);
-	if (read_full(fd, buf, st_size) != st_size) {
+	fip->buffer = xmalloc(st_size);
+	if (read_full(fd, fip->buffer, st_size) != st_size) {
 		pr_err("Failed to read %s: %m\n", filename);
 		return -errno;
 	}
 
-	bufend = buf + st_size;
+	bufend = fip->buffer + st_size;
 	close(fd);
 
 	if (st_size < sizeof(fip_toc_header_t)) {
@@ -193,7 +196,7 @@ int fip_parse(struct fip_state *fip,
 		return -ENODATA;
 	}
 
-	toc_header = (fip_toc_header_t *)buf;
+	toc_header = (fip_toc_header_t *)fip->buffer;
 	toc_entry = (fip_toc_entry_t *)(toc_header + 1);
 
 	if (toc_header->name != TOC_HEADER_NAME) {
@@ -223,7 +226,8 @@ int fip_parse(struct fip_state *fip,
 		 */
 		image = xzalloc(sizeof(*image));
 		image->toc_e = *toc_entry;
-		image->buffer = xmalloc(toc_entry->size);
+		image->buffer = fip->buffer + toc_entry->offset_address;
+		image->buf_no_free = true;
 		/* Overflow checks before memory copy. */
 		if (toc_entry->size > (uint64_t)-1 - toc_entry->offset_address) {
 			pr_err("FIP %s is corrupted: entry size exceeds 64 bit address space\n",
@@ -236,9 +240,6 @@ int fip_parse(struct fip_state *fip,
 			return -EINVAL;
 		}
 
-		memcpy(image->buffer, buf + toc_entry->offset_address,
-		    toc_entry->size);
-
 		/* If this is an unknown image, create a descriptor for it. */
 		desc = fip_lookup_image_desc_from_uuid(fip, &toc_entry->uuid);
 		if (desc == NULL) {
@@ -264,7 +265,7 @@ int fip_parse(struct fip_state *fip,
 		    filename);
 		return -EINVAL;
 	}
-	free(buf);
+
 	return 0;
 }
 
-- 
2.39.5





[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux