From 0be630aa265d11fab7dd9a2133a36b04e4753666 Mon Sep 17 00:00:00 2001 From: Shawn Nematbakhsh Date: Mon, 20 Jun 2016 16:49:04 -0700 Subject: [PATCH] npcx: vbnvcontext: Fix misaligned access We have no guarantee about the alignment of our input buffer so don't use 32-bit access. BUG=chrome-os-partner:54561 BRANCH=None TEST=Manual on gru. Enable CHROMEOS_VBNV_EC, verify exception isn't encountered on host command 0x17. Also verify call to system_set_vbnvcontext followed by system_get_vbnvcontext results in same data being read back. Signed-off-by: Shawn Nematbakhsh Change-Id: I4df636b70c71a43a2dd6f584ee965135e90b4351 Reviewed-on: https://chromium-review.googlesource.com/354132 Commit-Ready: Shawn N Tested-by: Shawn N Reviewed-by: Mulin Chao Reviewed-by: Vincent Palatin --- chip/npcx/system.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/chip/npcx/system.c b/chip/npcx/system.c index 0411892214..13695acf73 100644 --- a/chip/npcx/system.c +++ b/chip/npcx/system.c @@ -603,6 +603,8 @@ const char *system_get_chip_revision(void) return rev; } +BUILD_ASSERT(BBRM_DATA_INDEX_VBNVCNTXT + EC_VBNV_BLOCK_SIZE <= NPCX_BBRAM_SIZE); + /** * Get/Set VbNvContext in non-volatile storage. The block should be 16 bytes * long, which is the current size of VbNvContext block. @@ -613,23 +615,28 @@ const char *system_get_chip_revision(void) int system_get_vbnvcontext(uint8_t *block) { int i; - uint32_t *pblock = (uint32_t *) block; - for (i = 0; i < 4; i++) - pblock[i] = bbram_data_read(BBRM_DATA_INDEX_VBNVCNTXT + i*4); + + if (IS_BIT_SET(NPCX_BKUP_STS, NPCX_BKUP_STS_IBBR)) { + memset(block, 0, EC_VBNV_BLOCK_SIZE); + return EC_SUCCESS; + } + + for (i = 0; i < EC_VBNV_BLOCK_SIZE; ++i) + block[i] = NPCX_BBRAM(BBRM_DATA_INDEX_VBNVCNTXT + i); return EC_SUCCESS; } int system_set_vbnvcontext(const uint8_t *block) { - int i, result; - uint32_t *pblock = (uint32_t *) block; - for (i = 0; i < 4; i++) { - result = bbram_data_write(BBRM_DATA_INDEX_VBNVCNTXT + i*4, - pblock[i]); - if (result != EC_SUCCESS) - return result; - } + int i; + + if (IS_BIT_SET(NPCX_BKUP_STS, NPCX_BKUP_STS_IBBR)) + return EC_ERROR_INVAL; + + for (i = 0; i < EC_VBNV_BLOCK_SIZE; i++) + NPCX_BBRAM(BBRM_DATA_INDEX_VBNVCNTXT + i) = block[i]; + return EC_SUCCESS; }