summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorRob Barnes <robbarnes@google.com>2022-09-14 20:47:00 +0000
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-11-17 00:47:31 +0000
commitafdd762d014f295e19b71d789890e565d5b9286d (patch)
treedc4986e66945c4d246a056852f039fc2c5dce26f /common
parentec31407993ec9b5ae14fed72d728a4061d656d65 (diff)
downloadchrome-ec-afdd762d014f295e19b71d789890e565d5b9286d.tar.gz
system: Ensure space for panic and jump data
Ensure space is available for end of ram data. End of ram data must be located at the very end of noinit ram. This currently includes panic_data followed by jump_data. This is being enforced with linker asserts and build asserts rather than allocating the space directly so RAM utiliztion reports are still relevant. Introduce PLATFORM_EC_PRESERVED_END_OF_RAM_SIZE config option and default it to 1KB. This can be adjusted on boards that are constrained. BUG=b:246778588,b:246798928 BRANCH=None TEST=./twister -c -s zephyr/test/jump_tags/jump_tags.default && make run-kb_8042 Change-Id: I444bbe3a583396b4f9b104bb6999e78ae3ff6f2f Signed-off-by: Rob Barnes <robbarnes@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3896272 Reviewed-by: Aaron Massey <aaronmassey@google.com> Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-by: Fabio Baltieri <fabiobaltieri@google.com> Code-Coverage: Zoss <zoss-cl-coverage@prod.google.com>
Diffstat (limited to 'common')
-rw-r--r--common/panic_output.c12
-rw-r--r--common/system.c34
2 files changed, 43 insertions, 3 deletions
diff --git a/common/panic_output.c b/common/panic_output.c
index 2f92e65514..a5bba9d184 100644
--- a/common/panic_output.c
+++ b/common/panic_output.c
@@ -208,7 +208,7 @@ struct panic_data *get_panic_data_write(void)
* end of RAM.
*/
struct panic_data *const pdata_ptr = PANIC_DATA_PTR;
- const struct jump_data *jdata_ptr;
+ struct jump_data *jdata_ptr;
uintptr_t data_begin;
size_t move_size;
int delta;
@@ -264,6 +264,16 @@ struct panic_data *get_panic_data_write(void)
move_size = 0;
}
+ /* Check if there's enough space for jump tags after move */
+ if (data_begin - move_size < JUMP_DATA_MIN_ADDRESS) {
+ /* Not enough room for jump tags, clear tags.
+ * TODO(b/251190975): This failure should be reported
+ * in the panic data structure for more visibility.
+ */
+ move_size -= jdata_ptr->jump_tag_total;
+ jdata_ptr->jump_tag_total = 0;
+ }
+
data_begin -= move_size;
if (move_size != 0) {
diff --git a/common/system.c b/common/system.c
index 375cca2882..af5d670216 100644
--- a/common/system.c
+++ b/common/system.c
@@ -67,6 +67,11 @@ static enum ec_reboot_cmd reboot_at_shutdown;
static enum sysinfo_flags system_info_flags;
+/* Ensure enough space for panic_data, jump_data and at least one jump tag */
+BUILD_ASSERT((sizeof(struct panic_data) + sizeof(struct jump_data) +
+ JUMP_TAG_MAX_SIZE) <= CONFIG_PRESERVED_END_OF_RAM_SIZE,
+ "End of ram data size is too small for panic and jump data");
+
STATIC_IF(CONFIG_HIBERNATE) uint32_t hibernate_seconds;
STATIC_IF(CONFIG_HIBERNATE) uint32_t hibernate_microseconds;
@@ -349,15 +354,24 @@ test_mockable int system_jumped_late(void)
int system_add_jump_tag(uint16_t tag, int version, int size, const void *data)
{
struct jump_tag *t;
+ size_t new_entry_size;
/* Only allowed during a sysjump */
if (!jdata || jdata->magic != JUMP_DATA_MAGIC)
return EC_ERROR_UNKNOWN;
/* Make room for the new tag */
- if (size > 255)
+ if (size > JUMP_TAG_MAX_SIZE)
return EC_ERROR_INVAL;
- jdata->jump_tag_total += ROUNDUP4(size) + sizeof(struct jump_tag);
+
+ new_entry_size = ROUNDUP4(size) + sizeof(struct jump_tag);
+
+ if (system_usable_ram_end() - new_entry_size < JUMP_DATA_MIN_ADDRESS) {
+ ccprintf("ERROR: out of space for jump tags\n");
+ return EC_ERROR_INVAL;
+ }
+
+ jdata->jump_tag_total += new_entry_size;
t = (struct jump_tag *)system_usable_ram_end();
t->tag = tag;
@@ -378,6 +392,10 @@ test_mockable const uint8_t *system_get_jump_tag(uint16_t tag, int *version,
if (!jdata)
return NULL;
+ /* Ensure system_usable_ram_end() is within bounds */
+ if (system_usable_ram_end() < JUMP_DATA_MIN_ADDRESS)
+ return NULL;
+
/* Search through tag data for a match */
while (used < jdata->jump_tag_total) {
/* Check the next tag */
@@ -918,6 +936,18 @@ void system_common_pre_init(void)
else
delta = sizeof(struct jump_data) - jdata->struct_size;
+ /*
+ * Check if enough space for jump data.
+ * Clear jump data and return if not.
+ */
+ if (system_usable_ram_end() < JUMP_DATA_MIN_ADDRESS) {
+ /* TODO(b/251190975): This failure should be reported
+ * in the panic data structure for more visibility.
+ */
+ memset(jdata, 0, sizeof(struct jump_data));
+ return;
+ }
+
if (delta && jdata->jump_tag_total) {
uint8_t *d = (uint8_t *)system_usable_ram_end();
memmove(d, d + delta, jdata->jump_tag_total);