diff options
-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); |