From dd7a7743440846d706583bc2db9317ef1bbf3d45 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 10 Dec 2012 16:20:42 -0800 Subject: tlcl: move open retry into Tlcl Make sure all Tlcl users benefit from the new retry logic. BUG=None TEST=daisy build, manual testing of racing tpmc loops BRANCH=None Change-Id: I8e9656a65b5d6b45694c1c8bceb95f54f7c751bb Signed-off-by: Kees Cook Reviewed-on: https://gerrit.chromium.org/gerrit/39525 Reviewed-by: Luigi Semenzato --- firmware/stub/tpm_lite_stub.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'firmware/stub') diff --git a/firmware/stub/tpm_lite_stub.c b/firmware/stub/tpm_lite_stub.c index a60d6507..60065e64 100644 --- a/firmware/stub/tpm_lite_stub.c +++ b/firmware/stub/tpm_lite_stub.c @@ -21,9 +21,13 @@ #include #include #include +#include #include #define TPM_DEVICE_PATH "/dev/tpm0" +/* Retry failed open()s for 5 seconds in 10ms polling intervals. */ +#define OPEN_RETRY_DELAY_NS (10 * 1000 * 1000) +#define OPEN_RETRY_MAX_NUM 500 /* TODO: these functions should pass errors back rather than returning void */ /* TODO: if the only callers to these are just wrappers, should just @@ -143,6 +147,8 @@ VbError_t VbExTpmClose(void) { VbError_t VbExTpmOpen(void) { char* device_path; + struct timespec delay; + int retries, saved_errno; if (tpm_fd >= 0) return VBERROR_SUCCESS; /* Already open */ @@ -152,13 +158,25 @@ VbError_t VbExTpmOpen(void) { device_path = TPM_DEVICE_PATH; } - tpm_fd = open(device_path, O_RDWR); - if (tpm_fd < 0) { - return DoError(TPM_E_NO_DEVICE, "TPM: Cannot open TPM device %s: %s\n", - device_path, strerror(errno)); + /* Retry TPM opens on EBUSY failures. */ + for (retries = 0; retries < OPEN_RETRY_MAX_NUM; ++ retries) { + errno = 0; + tpm_fd = open(device_path, O_RDWR); + saved_errno = errno; + if (tpm_fd >= 0) + return VBERROR_SUCCESS; + if (saved_errno != EBUSY) + break; + + VBDEBUG(("TPM: retrying %s: %s\n", device_path, strerror(errno))); + + /* Stall until TPM comes back. */ + delay.tv_sec = 0; + delay.tv_nsec = OPEN_RETRY_DELAY_NS; + nanosleep(&delay, NULL); } - - return VBERROR_SUCCESS; + return DoError(TPM_E_NO_DEVICE, "TPM: Cannot open TPM device %s: %s\n", + device_path, strerror(saved_errno)); } -- cgit v1.2.1