summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2018-01-10 18:34:46 -0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2018-02-01 00:48:20 +0000
commita3d316b2b86d3c79129eecbd08c922b3b08d485c (patch)
tree3daa7100c53a5be8680866bcf3272fb6fcca92fc
parent7e35f6e9579e57bc0c100c7fe1979220356795aa (diff)
downloadchrome-ec-a3d316b2b86d3c79129eecbd08c922b3b08d485c.tar.gz
ccd: use async TPM reset where required
When TPM is wiped out on 'ccd open', the TPM reset could be invoked on the TPM task context, if physical presence verification was not required, or on the hooks task context, if PP was required. This patch makes sure that the proper TPM reset is invoked depending on the context. Also fixing the return value in ccd_command_wrapper(), because it is expected to be from the ec_error_list enun, and this is what is returned in the vendor command error response payload. BRANCH=cr50 BUG=b:62537474 TEST=verified that TPM and device reset happen smoothly in both cases when 'ccd open' requires and does not require PP. Change-Id: I1935fc90b386bb8f2158001e153da371fca22d03 Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/861206 Reviewed-by: Randall Spangler <rspangler@chromium.org> (cherry picked from commit b95b487cbcdadd1e9026dee255cebbe7660dd549) Reviewed-on: https://chromium-review.googlesource.com/896784
-rw-r--r--common/ccd_config.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/common/ccd_config.c b/common/ccd_config.c
index 01d8c8ae6f..6f65626849 100644
--- a/common/ccd_config.c
+++ b/common/ccd_config.c
@@ -567,24 +567,45 @@ static int ccd_set_password(const char *password)
/******************************************************************************/
/* Handlers for state changes requiring physical presence */
-static void ccd_open_done(void)
+/*
+ * Could be invoked synchronously on the TPM task context, or asynchronously,
+ * after physical presence is established, on the hooks task context.
+ *
+ * The appropriate TPM reset entry point needs to be invoked. Also, make sure
+ * that the board is always rebooted when TPM is reset.
+ *
+ * @param sync Non-zero to invoke synchronously.
+ */
+static void ccd_open_done(int sync)
{
+ int rv;
+
if (!ccd_is_cap_enabled(CCD_CAP_OPEN_WITHOUT_TPM_WIPE)) {
/* Can't open unless wipe succeeds */
- if (tpm_sync_reset(1) != EC_SUCCESS) {
+ if (sync)
+ rv = tpm_sync_reset(1);
+ else
+ rv = board_wipe_tpm();
+
+ if (rv != EC_SUCCESS) {
CPRINTS("CCD open TPM wipe failed");
return;
}
}
if (!ccd_is_cap_enabled(CCD_CAP_UNLOCK_WITHOUT_AP_REBOOT) ||
- !ccd_is_cap_enabled(CCD_CAP_OPEN_WITHOUT_TPM_WIPE))
+ (!ccd_is_cap_enabled(CCD_CAP_OPEN_WITHOUT_TPM_WIPE) && sync))
board_reboot_ap();
CPRINTS("CCD opened");
ccd_set_state(CCD_STATE_OPENED);
}
+static void ccd_open_done_async(void)
+{
+ ccd_open_done(0);
+}
+
static void ccd_unlock_done(void)
{
if (!ccd_is_cap_enabled(CCD_CAP_UNLOCK_WITHOUT_AP_REBOOT))
@@ -858,8 +879,7 @@ static int ccd_command_wrapper(int argc, char *password,
*/
return_code = be32toh(vch->tpm_header.command_code);
if (return_code && (return_code != VENDOR_RC_IN_PROGRESS)) {
- ccprintf("Command error %d\n", vch->ccd_subcommand);
- rv = EC_ERROR_UNKNOWN;
+ rv = vch->ccd_subcommand;
} else {
rv = EC_SUCCESS;
}
@@ -933,7 +953,7 @@ static enum vendor_cmd_rc ccd_open(void *buf,
if (need_pp) {
/* Start physical presence detect */
ccprintf("Starting CCD open...\n");
- rv = physical_detect_start(is_long, ccd_open_done);
+ rv = physical_detect_start(is_long, ccd_open_done_async);
if (rv != EC_SUCCESS) {
*response_size = 1;
buffer[0] = rv;
@@ -943,7 +963,7 @@ static enum vendor_cmd_rc ccd_open(void *buf,
}
/* No physical presence required; go straight to done */
- ccd_open_done();
+ ccd_open_done(1);
return VENDOR_RC_SUCCESS;
}