blob: d88af038a045ed674d002bc44d01ac16d181e6e0 [file] [log] [blame]
From 5ee1e5bca5c2b5e5b4ac26e734e71514f47cd0c2 Mon Sep 17 00:00:00 2001
From: Andrey Pronin <apronin@chromium.org>
Date: Thu, 6 Apr 2017 13:34:20 -0700
Subject: [PATCH] CHROMIUM: tpm: block messages while suspended
Other drivers or userspace may initiate sending a message to the tpm
while the device itself and the controller of the bus it is on are
suspended. That may break the bus driver logic.
Block sending messages while the device is suspended.
BUG=b:35648537
TEST=Continuously send messages to the tpm, go through suspend
to S0ix and back. Check that messages are rejected while
the tpm is suspended, and the tpm is accessible after resume.
Change-Id: If5e2ee33ecb9e8e4afec20b2cf1b232b42859547
Signed-off-by: Andrey Pronin <apronin@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/470747
Reviewed-by: Duncan Laurie <dlaurie@google.com>
Conflicts:
drivers/char/tpm/tpm-interface.c
drivers/char/tpm/tpm.h
[rebase412(groeck): Resolved conflicts (context changes)]
Signed-off-by: Guenter Roeck <groeck@chromium.org>
Conflicts:
drivers/char/tpm/tpm-interface.c
drivers/char/tpm/tpm.h
[rebase419(groeck): Resolved conflicts (context changes)]
Signed-off-by: Guenter Roeck <groeck@chromium.org>
[rebase54(groeck): Context conflicts;
replaced is_suspended bit operations with boolean]
Signed-off-by: Guenter Roeck <groeck@chromium.org>
[rebase510(groeck): Context conflicts]
Signed-off-by: Guenter Roeck <groeck@chromium.org>
---
drivers/char/tpm/tpm-interface.c | 9 ++++++++-
include/linux/tpm.h | 2 ++
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 586ca10b0d72e5a0ed6fb84171b8ba1754def0d8..2f568196e8c4ae31a74dbf061b38c0eb91fa6699 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -82,6 +82,11 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip, void *buf, size_t bufsiz)
return -E2BIG;
}
+ if (chip->is_suspended) {
+ dev_warn(&chip->dev, "blocking transmit while suspended\n");
+ return -EAGAIN;
+ }
+
rc = chip->ops->send(chip, buf, count);
if (rc < 0) {
if (rc != -EPIPE)
@@ -411,6 +416,8 @@ int tpm_pm_suspend(struct device *dev)
tpm_put_ops(chip);
}
+ if (!rc)
+ chip->is_suspended = true;
suspended:
chip->flags |= TPM_CHIP_FLAG_SUSPENDED;
@@ -438,7 +445,7 @@ int tpm_pm_resume(struct device *dev)
* activate before the chip has been fully resumed.
*/
wmb();
-
+ chip->is_suspended = false;
return 0;
}
EXPORT_SYMBOL_GPL(tpm_pm_resume);
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index 6eca8f544dfadbcd111dfdd8fd511fb43d7188a4..77b521ca4975111e38243a26be575bf1d233ad64 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -138,6 +138,8 @@ struct tpm_chip {
int dev_num; /* /dev/tpm# */
unsigned long is_open; /* only one allowed */
+ bool is_suspended;
+
char hwrng_name[64];
struct hwrng hwrng;
--
2.34.1