diff options
author | Bill Richardson <wfrichar@chromium.org> | 2016-11-16 15:37:44 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-11-19 00:14:24 -0800 |
commit | 93388bc758cf7c2cfc70f63fbe42c25b1ed7fb38 (patch) | |
tree | 49310e932f37812d771166b9f3778906f37f232f /board/cr50/wp.c | |
parent | 7f8ad649dd1a417a746739e86bce7dc3f0a40c1b (diff) | |
download | chrome-ec-93388bc758cf7c2cfc70f63fbe42c25b1ed7fb38.tar.gz |
Cr50: Prevent rebooting when unlocking the console
When the console is unlocked, the function nvmem_wipe_or_reboot()
is called. This holds the EC in reset, clears nvmem, resets the
TPM task, then releases the EC. Nothing about that should cause
the Cr50 to reboot, but it was happening anyway.
This CL addresses several subtle problems.
First, holding the EC in reset invoked the sys_rst_asserted()
interrupt handler, triggering extra (and early) calls to
tpm_reset(). That should wait until after nvmem is cleared, and
only be called once.
Second, the intentional call to tpm_reset() caused the current
(HOOKS) task to wait for the operation to finish, but it didn't
wait long enough (recreating the endorsement certs can take over
a second). When the task_wake_event() returned, a timeout was
indicated in addition to the completion event.
Third, because we checked for the timeout first, we reported an
error even though tpm_reset() completed successfully, just slower
than we expected. We didn't get the timeout event before it
completed because the TPM task runs at a higher priority.
This CL addresses all of these cases, and makes wiping nvmem the
responsibility of the TPM task as well, so that it can do it when it's
ready.
Note that the EC (and thus AP too) will be held in reset while nvmem is
erased.
BUG=chrome-os-partner:59902
BRANCH=none
TEST=make buildall, manual tests
From the Cr50 console, run the "lock on" and "lock off" commands.
Try it both with and without the battery present. Observe that
the Cr50 no longer reboots just because the console unlocks.
Change-Id: I65a342502718acc5b9bda8c6f28dcd27e8f027f7
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/411379
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
Diffstat (limited to 'board/cr50/wp.c')
-rw-r--r-- | board/cr50/wp.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/board/cr50/wp.c b/board/cr50/wp.c index d667ecc74e..69b88c4a71 100644 --- a/board/cr50/wp.c +++ b/board/cr50/wp.c @@ -13,6 +13,7 @@ #include "system.h" #include "task.h" #include "timer.h" +#include "tpm_registers.h" #define CPRINTS(format, args...) cprints(CC_RBOX, format, ## args) #define CPRINTF(format, args...) cprintf(CC_RBOX, format, ## args) @@ -58,7 +59,21 @@ static void lock_the_console(void) static void unlock_the_console(void) { - nvmem_wipe_or_reboot(); + int rc; + + /* Wipe the TPM's memory and reset the TPM task. */ + rc = tpm_reset(1, 1); + if (rc != EC_SUCCESS) { + /* + * If anything goes wrong (which is unlikely), we REALLY don't + * want to unlock the console. It's possible to fail without + * the TPM task ever running, so rebooting is probably our best + * bet for fixing the problem. + */ + CPRINTS("%s: Couldn't wipe nvmem! (rc %d)", __func__, rc); + system_reset(SYSTEM_RESET_HARD); + } + CPRINTS("TPM is erased, console is unlocked"); console_restricted_state = 0; } |