summaryrefslogtreecommitdiff
path: root/firmware/stub
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 /firmware/stub
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>
Diffstat (limited to 'firmware/stub')
-rw-r--r--firmware/stub/tpm_lite_stub.c30
1 files changed, 24 insertions, 6 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));
}