summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@chromium.org>2018-04-09 11:18:15 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-05-07 20:45:54 -0700
commit6e8cbe40eea777aeaeffe0fa0781a0a5d1763a4d (patch)
treed229d77bb060be8ba34d4bf94d257ac035c89c26
parentc24d480d90699bf6aaf534d66dc48513d867bdd0 (diff)
downloadchrome-ec-6e8cbe40eea777aeaeffe0fa0781a0a5d1763a4d.tar.gz
shared_mem: Assert that shared memory size is large enough
We add a configuration option to set the minimum shared memory size (CONFIG_SHAREDMEM_MINIMUM_SIZE), so that the link will fail if there is not enough IRAM left. Also, we add 2 macros around shared_mem_acquire, that check, at build time, that the shared memory size is sufficient for the allocation: - SHARED_MEM_ACQUIRE_CHECK should be used instead of shared_mem_acquire, when size is known in advance. - SHARED_MEM_CHECK_SIZE should be used when only a maximum size is known. This does not account for "jump tags" that boards often add on jump from RO to RW. Luckily, RW usually does not do verification, and does not need as much shared memory. BRANCH=none BUG=chromium:739771 TEST=make buildall -j, no error Change-Id: Ic4c72938affe65fe8f8bc17ee5111c1798fc536f Signed-off-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1002713 Reviewed-by: Gwendal Grignou <gwendal@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org> Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r--common/host_command.c2
-rw-r--r--common/keyboard_8042.c2
-rw-r--r--common/nvmem_vars.c2
-rw-r--r--common/rwsig.c2
-rw-r--r--common/vboot/common.c2
-rw-r--r--common/vboot_hash.c3
-rw-r--r--core/cortex-m/ec.lds.S4
-rw-r--r--core/cortex-m0/ec.lds.S4
-rw-r--r--core/nds32/ec.lds.S4
-rw-r--r--include/config.h30
-rw-r--r--include/shared_mem.h9
11 files changed, 59 insertions, 5 deletions
diff --git a/common/host_command.c b/common/host_command.c
index c8d01a3d6f..0900d9e1d4 100644
--- a/common/host_command.c
+++ b/common/host_command.c
@@ -838,7 +838,7 @@ static int command_host_command(int argc, char **argv)
int rv;
/* Use shared memory for command params space */
- if (shared_mem_acquire(EC_PROTO2_MAX_PARAM_SIZE, &cmd_params)) {
+ if (SHARED_MEM_ACQUIRE_CHECK(EC_PROTO2_MAX_PARAM_SIZE, &cmd_params)) {
ccputs("Can't acquire shared memory buffer.\n");
return EC_ERROR_UNKNOWN;
}
diff --git a/common/keyboard_8042.c b/common/keyboard_8042.c
index b18be07649..91d640fde8 100644
--- a/common/keyboard_8042.c
+++ b/common/keyboard_8042.c
@@ -1052,7 +1052,7 @@ static int command_keyboard_log(int argc, char **argv)
if (i) {
if (!kblog_buf) {
- int rv = shared_mem_acquire(
+ int rv = SHARED_MEM_ACQUIRE_CHECK(
sizeof(*kblog_buf) * MAX_KBLOG,
(char **)&kblog_buf);
if (rv != EC_SUCCESS)
diff --git a/common/nvmem_vars.c b/common/nvmem_vars.c
index af0981f1f0..78b2d146c5 100644
--- a/common/nvmem_vars.c
+++ b/common/nvmem_vars.c
@@ -33,7 +33,7 @@ int get_local_copy(void)
if (rbuf)
return EC_SUCCESS;
- rv = shared_mem_acquire(CONFIG_FLASH_NVMEM_VARS_USER_SIZE,
+ rv = SHARED_MEM_ACQUIRE_CHECK(CONFIG_FLASH_NVMEM_VARS_USER_SIZE,
(char **)&rbuf);
if (rv == EC_SUCCESS) {
diff --git a/common/rwsig.c b/common/rwsig.c
index c2703234b6..7164e2e208 100644
--- a/common/rwsig.c
+++ b/common/rwsig.c
@@ -131,7 +131,7 @@ int rwsig_check_signature(void)
#endif
/* Large buffer for RSA computation : could be re-use afterwards... */
- res = shared_mem_acquire(3 * RSANUMBYTES, (char **)&rsa_workbuf);
+ res = SHARED_MEM_ACQUIRE_CHECK(3 * RSANUMBYTES, (char **)&rsa_workbuf);
if (res) {
CPRINTS("No memory for RW verification");
goto out;
diff --git a/common/vboot/common.c b/common/vboot/common.c
index 3a4af244a2..39f8c193c7 100644
--- a/common/vboot/common.c
+++ b/common/vboot/common.c
@@ -40,7 +40,7 @@ int vboot_verify(const uint8_t *data, int len,
uint32_t *workbuf;
int err = EC_SUCCESS;
- if (shared_mem_acquire(3 * RSANUMBYTES, (char **)&workbuf))
+ if (SHARED_MEM_ACQUIRE_CHECK(3 * RSANUMBYTES, (char **)&workbuf))
return EC_ERROR_MEMORY_ALLOCATION;
/* Compute hash of the RW firmware */
diff --git a/common/vboot_hash.c b/common/vboot_hash.c
index e6b83aafe3..b7f0be32f2 100644
--- a/common/vboot_hash.c
+++ b/common/vboot_hash.c
@@ -34,6 +34,9 @@ struct vboot_hash_tag {
#define CHUNK_SIZE 1024 /* Bytes to hash per deferred call */
#define WORK_INTERVAL_US 100 /* Delay between deferred calls */
+/* Check that CHUNK_SIZE fits in shared memory. */
+SHARED_MEM_CHECK_SIZE(CHUNK_SIZE);
+
static uint32_t data_offset;
static uint32_t data_size;
static uint32_t curr_pos;
diff --git a/core/cortex-m/ec.lds.S b/core/cortex-m/ec.lds.S
index 25ce2ef221..b6882d7214 100644
--- a/core/cortex-m/ec.lds.S
+++ b/core/cortex-m/ec.lds.S
@@ -348,6 +348,10 @@ SECTIONS
/* NOTHING MAY GO AFTER THIS! */
} > IRAM
+ ASSERT((__shared_mem_buf + CONFIG_SHAREDMEM_MINIMUM_SIZE) <=
+ (CONFIG_RAM_BASE + CONFIG_RAM_SIZE),
+ "Not enough space for shared memory.")
+
/* The linker won't notice if the .data section is too big to fit,
* apparently because we're sending it into IRAM, not FLASH. The following
* symbol isn't used by the code, but running "objdump -t *.elf | grep hey"
diff --git a/core/cortex-m0/ec.lds.S b/core/cortex-m0/ec.lds.S
index 86f5494797..26515451d3 100644
--- a/core/cortex-m0/ec.lds.S
+++ b/core/cortex-m0/ec.lds.S
@@ -222,6 +222,10 @@ SECTIONS
/* NOTHING MAY GO AFTER THIS! */
} > IRAM
+ ASSERT((__shared_mem_buf + CONFIG_SHAREDMEM_MINIMUM_SIZE) <=
+ (CONFIG_RAM_BASE + CONFIG_RAM_SIZE),
+ "Not enough space for shared memory.")
+
/* The linker won't notice if the .data section is too big to fit,
* apparently because we're sending it into IRAM, not FLASH. The following
* symbol isn't used by the code, but running "objdump -t *.elf | grep hey"
diff --git a/core/nds32/ec.lds.S b/core/nds32/ec.lds.S
index c2897343e6..807534f512 100644
--- a/core/nds32/ec.lds.S
+++ b/core/nds32/ec.lds.S
@@ -220,6 +220,10 @@ SECTIONS
} > IRAM
+ ASSERT((__shared_mem_buf + CONFIG_SHAREDMEM_MINIMUM_SIZE) <=
+ (CONFIG_RAM_BASE + CONFIG_RAM_SIZE),
+ "Not enough space for shared memory.")
+
__image_size = LOADADDR(.data) + SIZEOF(.data) - FW_OFF(SECTION);
#ifdef CONFIG_LPC
diff --git a/include/config.h b/include/config.h
index feb7de7903..0ce98481e3 100644
--- a/include/config.h
+++ b/include/config.h
@@ -3345,6 +3345,36 @@
/******************************************************************************/
/*
+ * Set minimum shared memory size, unless it is defined in board file.
+ */
+#ifndef CONFIG_SHAREDMEM_MINIMUM_SIZE
+#ifdef CONFIG_COMMON_RUNTIME
+/* If RWSIG is used, we may need more space. */
+#if defined(CONFIG_RWSIG)
+#define CONFIG_SHAREDMEM_MINIMUM_SIZE_RWSIG (CONFIG_RSA_KEY_SIZE / 8 * 3)
+#else
+#define CONFIG_SHAREDMEM_MINIMUM_SIZE_RWSIG 0
+#endif
+
+/*
+ * We can't use the "MAX" function here, as it is too smart and BUILD_ASSERT
+ * calls do not allow it as parameter. BUILD_MAX below works for both compiler
+ * and linker.
+ */
+#define BUILD_MAX(x, y) ((x) > (y) ? (x) : (y))
+
+/* Minimum: 1kb */
+#define CONFIG_SHAREDMEM_MINIMUM_SIZE \
+ BUILD_MAX(1024, CONFIG_SHAREDMEM_MINIMUM_SIZE_RWSIG)
+#else /* !CONFIG_COMMON_RUNTIME */
+/* Without common runtime, we do not have support for shared memory. */
+#define CONFIG_SHAREDMEM_MINIMUM_SIZE 0
+#endif
+#endif /* !CONFIG_SHAREDMEM_MINIMUM_SIZE */
+
+
+/******************************************************************************/
+/*
* Disable the built-in console history if using the experimental console.
*
* The experimental console keeps its own session-persistent history which
diff --git a/include/shared_mem.h b/include/shared_mem.h
index f69730b311..75b295b584 100644
--- a/include/shared_mem.h
+++ b/include/shared_mem.h
@@ -26,6 +26,9 @@
*/
int shared_mem_size(void);
+#define SHARED_MEM_CHECK_SIZE(size) \
+ BUILD_ASSERT((size) <= CONFIG_SHAREDMEM_MINIMUM_SIZE)
+
/*
* Acquires a shared memory area of the requested size in bytes.
*
@@ -43,6 +46,12 @@ int shared_mem_size(void);
*/
int shared_mem_acquire(int size, char **dest_ptr);
+#define SHARED_MEM_ACQUIRE_CHECK(size, dest_ptr) \
+ ({ \
+ SHARED_MEM_CHECK_SIZE(size); \
+ shared_mem_acquire((size), (dest_ptr)); \
+ })
+
/**
* Releases a shared memory area previously allocated via shared_mem_acquire().
*/