Attention is currently required from: Christian Walter, Julius Werner, Yu-Ping Wu.
Jon Murphy has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/77667?usp=email )
Change subject: drivers/tpm: Add tpm failure handling ......................................................................
drivers/tpm: Add tpm failure handling
Add additional failure mode logic for the TPM to enable an automated recovery mode for GSC hangs.
BUG=b:296439237 TEST=Force the error by hard coding the return code and observe the device entering hibernate. BRANCH=firmware-skyrim-15390.B
Change-Id: Iee764f5ff2b78eef202ae0b3e30b0608141cbbe2
Change-Id: Ieec7e9227d538130354dea8b772d0306cdda1237 Signed-off-by: Jon Murphy jpmurphy@google.com --- M src/security/tpm/Kconfig M src/security/vboot/vboot_logic.c 2 files changed, 22 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/67/77667/1
diff --git a/src/security/tpm/Kconfig b/src/security/tpm/Kconfig index 39134c1..661231a 100644 --- a/src/security/tpm/Kconfig +++ b/src/security/tpm/Kconfig @@ -172,3 +172,11 @@ default 3
endmenu # Trusted Platform Module (tpm) + +config TPM_SETUP_HIBERNATE_ON_ERR + bool + depends on EC_GOOGLE_CHROMEEC + help + Select this to force a device to hibernate on TPM setup error to turn the TPM + off. This is only effective if the Z-State brings the power rail down. This + is used to cold boot the entire system to attempt to recover the TPM. diff --git a/src/security/vboot/vboot_logic.c b/src/security/vboot/vboot_logic.c index f167437..10f6eab 100644 --- a/src/security/vboot/vboot_logic.c +++ b/src/security/vboot/vboot_logic.c @@ -4,6 +4,7 @@ #include <assert.h> #include <console/console.h> #include <bootmode.h> +#include <ec/google/chromeec/ec.h> #include <fmap.h> #include <security/tpm/tspi/crtm.h> #include <security/tpm/tss/vendor/cr50/cr50.h> @@ -265,9 +266,21 @@ * check the return value here because vb2api_fw_phase1 will catch * invalid secdata and tell us what to do (=reboot). */ timestamp_add_now(TS_TPMINIT_START); - if (vboot_setup_tpm(ctx) == TPM_SUCCESS) { + rv = vboot_setup_tpm(ctx); + if (rv == TPM_SUCCESS) { antirollback_read_space_firmware(ctx); antirollback_read_space_kernel(ctx); + } else if (CONFIG(TPM_SETUP_HIBERNATE_ON_ERR) && + rv == TPM_COMMUNICATION_ERROR) { + printk(BIOS_ERR, "Failed to communicate with TPM\n" + "Next reboot will hibernate to reset TPM"); + /* Command the EC to hibernate on next AP shutdown */ + if (google_chromeec_reboot( + EC_REBOOT_HIBERNATE, + EC_REBOOT_FLAG_ON_AP_SHUTDOWN)) { + printk(BIOS_ERR, "Failed to get EC to schedule hibernate"); + } + vb2api_fail(ctx, VB2_RECOVERY_RO_TPM_S_ERROR, rv); } timestamp_add_now(TS_TPMINIT_END);