summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2012-12-10 16:20:42 -0800
committerGerrit <chrome-bot@google.com>2012-12-12 13:37:33 -0800
commitdd7a7743440846d706583bc2db9317ef1bbf3d45 (patch)
tree52e4bc56d505c5fc4d9c9da6e57cffa12b103f19
parenta4090b5a61d7b86ee6b3a51090ec27cd7c10944c (diff)
downloadvboot-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.c30
-rw-r--r--utility/mount-encrypted.c23
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);