diff options
author | Kees Cook <keescook@chromium.org> | 2012-12-10 16:20:42 -0800 |
---|---|---|
committer | Gerrit <chrome-bot@google.com> | 2012-12-12 13:37:33 -0800 |
commit | dd7a7743440846d706583bc2db9317ef1bbf3d45 (patch) | |
tree | 52e4bc56d505c5fc4d9c9da6e57cffa12b103f19 | |
parent | a4090b5a61d7b86ee6b3a51090ec27cd7c10944c (diff) | |
download | vboot-dd7a7743440846d706583bc2db9317ef1bbf3d45.tar.gz |
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 <keescook@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/39525
Reviewed-by: Luigi Semenzato <semenzato@chromium.org>
-rw-r--r-- | firmware/stub/tpm_lite_stub.c | 30 | ||||
-rw-r--r-- | utility/mount-encrypted.c | 23 |
2 files changed, 26 insertions, 27 deletions
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 <sys/time.h> #include <sys/types.h> #include <sys/stat.h> +#include <time.h> #include <unistd.h> #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)); } diff --git a/utility/mount-encrypted.c b/utility/mount-encrypted.c index 39777e9d..d453b6b0 100644 --- a/utility/mount-encrypted.c +++ b/utility/mount-encrypted.c @@ -115,33 +115,14 @@ static int tpm_init_called = 0; static void tpm_init(void) { uint32_t result; - struct timespec delay; - int retries; if (tpm_init_called) return; DEBUG("Opening TPM"); - setenv("TPM_NO_EXIT", "1", 1); - - /* Retry TPM opening for 5 seconds (500 10ms sleeps). */ - for (retries = 0; retries < 500; ++ retries) { - errno = 0; - result = TlclLibInit(); - if (result == TPM_SUCCESS) - break; - INFO("Could not open TPM: error 0x%02x (%s).", result, - strerror(errno)); - /* Assume ENOENT will never recover */ - if (errno == ENOENT) - break; - - /* Stall 10ms until TPM comes back. */ - delay.tv_sec = 0; - delay.tv_nsec = 10000000; - nanosleep(&delay, NULL); - } + setenv("TPM_NO_EXIT", "1", 1); + result = TlclLibInit(); tpm_init_called = 1; has_tpm = (result == TPM_SUCCESS); |