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=None Change-Id: Ieec7e9227d538130354dea8b772d0306cdda1237 Signed-off-by: Jon Murphy <jpmurphy@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/77667 Reviewed-by: Eric Lai <eric_lai@quanta.corp-partner.google.com> Reviewed-by: Julius Werner <jwerner@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
		| @@ -172,3 +172,12 @@ config PCR_RUNTIME_DATA | |||||||
| 	default 3 | 	default 3 | ||||||
|  |  | ||||||
| endmenu # Trusted Platform Module (tpm) | 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 the next AP shutdown when a TPM | ||||||
|  | 	  setup error occurs. This will cause a cold boot of the system and offer an | ||||||
|  | 	  opportunity to recover the TPM should it be hung. This is only effective if | ||||||
|  | 	  the Z-State brings the power rail down. | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ | |||||||
| #include <assert.h> | #include <assert.h> | ||||||
| #include <console/console.h> | #include <console/console.h> | ||||||
| #include <bootmode.h> | #include <bootmode.h> | ||||||
|  | #include <ec/google/chromeec/ec.h> | ||||||
| #include <fmap.h> | #include <fmap.h> | ||||||
| #include <security/tpm/tspi/crtm.h> | #include <security/tpm/tspi/crtm.h> | ||||||
| #include <security/tpm/tss/vendor/cr50/cr50.h> | #include <security/tpm/tss/vendor/cr50/cr50.h> | ||||||
| @@ -271,9 +272,23 @@ void verstage_main(void) | |||||||
| 	 * check the return value here because vb2api_fw_phase1 will catch | 	 * check the return value here because vb2api_fw_phase1 will catch | ||||||
| 	 * invalid secdata and tell us what to do (=reboot). */ | 	 * invalid secdata and tell us what to do (=reboot). */ | ||||||
| 	timestamp_add_now(TS_TPMINIT_START); | 	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_firmware(ctx); | ||||||
| 		antirollback_read_space_kernel(ctx); | 		antirollback_read_space_kernel(ctx); | ||||||
|  | 	} else { | ||||||
|  | 		vb2api_fail(ctx, VB2_RECOVERY_RO_TPM_S_ERROR, rv); | ||||||
|  | 		if (CONFIG(TPM_SETUP_HIBERNATE_ON_ERR) && | ||||||
|  | 				rv == TPM_CB_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"); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 	timestamp_add_now(TS_TPMINIT_END); | 	timestamp_add_now(TS_TPMINIT_END); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user