cr50: reinstate nvmem commits 3 s after tpm reset

Relying on the AP sending a PCR read as an indication of the completed
boot process does not work on the resume path. Let's just enable
commits 3 s after they were stopped to process tpm reset.

BRANCH=none
BUG=chrome-os-partner:61795
TEST=observed the following on the cr50 console on a reef during reboot:

  [0.018692 tpm_init]
  tpm_manufactured: manufactured
  [0.021180 tpm_reset_now: done]
  .
  .
  [1.166496 Skipping commit]
  [1.425888 Skipping commit]
  [1.439112 Skipping commit]
  .
  .
  [3.021892 Committing NVMEM changes.]

  and verified that reef booted normally.

Change-Id: I5f64fe24b961a9d0366f8e4f40a0e44d4e7263fa
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/427328
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
Vadim Bendebury
2017-01-12 21:23:24 -08:00
committed by chrome-bot
parent 71ddb610c2
commit dfced0c191

View File

@@ -641,6 +641,7 @@ static void call_extension_command(struct tpm_cmd_header *tpmh,
/* Event (to TPM task) to request reset, or (from TPM task) on completion. */
#define TPM_EVENT_RESET TASK_EVENT_CUSTOM(1 << 0)
#define TPM_EVENT_COMMIT TASK_EVENT_CUSTOM(1 << 1)
/* Calling task (singular) to notify when the TPM reset has completed */
static __initialized task_id_t waiting_for_reset = TASK_ID_INVALID;
@@ -696,6 +697,20 @@ int tpm_is_resetting(void)
return reset_in_progress;
}
/*
* A timeout hook to reinstate NVMEM commits soon after reset.
*
* The TPM task disables nvmem commits during TPM reset, they need to be
* reinstated on the same task context. This is why an event is raised here to
* wake up the TPM task and force it to reinstate nvmem commits instead of
* doing it here directly.
*/
static void reinstate_nvmem_commits(void)
{
task_set_event(TASK_ID_TPM, TPM_EVENT_COMMIT, 0);
}
DECLARE_DEFERRED(reinstate_nvmem_commits);
static void tpm_reset_now(int wipe_first)
{
/* This is more related to TPM task activity than TPM transactions */
@@ -755,6 +770,13 @@ static void tpm_reset_now(int wipe_first)
}
cprints(CC_TASK, "%s: done", __func__);
/*
* The host might decide to do it sooner, but let's make sure commits
* do not stay disabled for more than 3 seconds.
*/
hook_call_deferred(&reinstate_nvmem_commits_data, 3 * SECOND);
reset_in_progress = 0;
}
@@ -772,8 +794,23 @@ void tpm_task(void)
evt = task_wait_event(-1);
if (evt & TPM_EVENT_RESET) {
tpm_reset_now(wipe_requested);
/*
* There is no point in looking at other events in
* this situation: the nvram will be committed by TPM
* reset; other tpm commands would be ignored.
*
* Let's just continue. This could change if there are
* other events added to the set.
*/
continue;
}
if (evt & TPM_EVENT_COMMIT)
nvmem_enable_commits();
if (!(evt & TASK_EVENT_WAKE))
continue;
tpmh = (struct tpm_cmd_header *)tpm_.regs.data_fifo;
command_code = be32toh(tpmh->command_code);
CPRINTF("%s: received fifo command 0x%04x\n",
@@ -801,20 +838,8 @@ void tpm_task(void)
* TODO(vbendeb): revisit this when
* crosbug.com/p/55667 has been addressed.
*/
if (command_code == TPM2_PCR_Read) {
if (command_code == TPM2_PCR_Read)
system_process_retry_counter();
/*
* The AP issuing a PCR Read command is
* considered an indication of the boot
* process being finished.
*
* There is no need to speed up TPM operations
* any more, pending NVMEM changes should be
* committed and future NVMEM commits should
* not be postponed.
*/
nvmem_enable_commits();
}
#ifdef CONFIG_EXTENSION_COMMAND
if (!IS_CUSTOM_CODE(command_code))
#endif