[Skiboot] [PATCH 1/2] libflash: Add checking at blocklevel for erase block aligned erase lengths

Cyril Bur cyril.bur at au1.ibm.com
Thu Jun 4 10:36:03 AEST 2015


Currently blocklevel_erase() will let any erase of any size get passed down
to the backend. Not strictly a problem since libflash does do this check
as well, however, not all future backends will.

This is very much a sanity check to save from a likely mistake.

Signed-off-by: Cyril Bur <cyril.bur at au1.ibm.com>
---
Hi Stewart,
These two should be applied after that one I needed to rebase:
https://patchwork.ozlabs.org/patch/479238/

 libflash/blocklevel.c | 10 ++++++++++
 libflash/blocklevel.h |  5 +++++
 libflash/libflash.c   |  1 +
 3 files changed, 16 insertions(+)

diff --git a/libflash/blocklevel.c b/libflash/blocklevel.c
index 35b8c8a..320ffac 100644
--- a/libflash/blocklevel.c
+++ b/libflash/blocklevel.c
@@ -15,6 +15,9 @@
  */
 
 #include <unistd.h>
+#include <stdio.h>
+
+#include <libflash/libflash.h>
 #include "blocklevel.h"
 
 int blocklevel_read(struct blocklevel_device *bl, uint32_t pos, void *buf, uint32_t len)
@@ -38,6 +41,13 @@ int blocklevel_erase(struct blocklevel_device *bl, uint32_t pos, uint32_t len)
 	if (!bl || !bl->erase)
 		return -1;
 
+	/* Programmer may be making a horrible mistake without knowing it */
+	if (len & bl->erase_mask) {
+		fprintf(stderr, "blocklevel_erase: len (0x%08x) is not erase block (0x%08x) aligned\n",
+				len, bl->erase_mask + 1);
+		return FLASH_ERR_ERASE_BOUNDARY;
+	}
+
 	return bl->erase(bl, pos, len);
 }
 
diff --git a/libflash/blocklevel.h b/libflash/blocklevel.h
index 2e8480d..41293ee 100644
--- a/libflash/blocklevel.h
+++ b/libflash/blocklevel.h
@@ -29,6 +29,11 @@ struct blocklevel_device {
 	int (*erase)(struct blocklevel_device *bl, uint32_t pos, uint32_t len);
 	int (*get_info)(struct blocklevel_device *bl, const char **name, uint32_t *total_size,
 			uint32_t *erase_granule);
+
+	/*
+	 * Keep the erase mask so that blocklevel_erase() can do sanity checking
+	 */
+	uint32_t erase_mask;
 };
 
 int blocklevel_read(struct blocklevel_device *bl, uint32_t pos, void *buf, uint32_t len);
diff --git a/libflash/libflash.c b/libflash/libflash.c
index 2af0c79..e7b3c8e 100644
--- a/libflash/libflash.c
+++ b/libflash/libflash.c
@@ -836,6 +836,7 @@ bail:
 	c->bl.write = &flash_smart_write;
 	c->bl.erase = &flash_erase;
 	c->bl.get_info = &flash_get_info;
+	c->bl.erase_mask = c->min_erase_mask;
 
 	*bl = &(c->bl);
 	return 0;
-- 
1.9.1



More information about the Skiboot mailing list