mirror of https://gitee.com/openkylin/linux.git
tpm: Introduce function to poll for result of self test
This patch introduces a function that runs the TPM_ContinueSelfTest() function and then polls the TPM to check whether it finished the selftest and can receive new commands. Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
This commit is contained in:
parent
d97c6ade59
commit
68d6e6713f
|
@ -627,7 +627,7 @@ static struct tpm_input_header continue_selftest_header = {
|
|||
* Returns 0 on success, < 0 in case of fatal error or a value > 0 representing
|
||||
* a TPM error code.
|
||||
*/
|
||||
int tpm_continue_selftest(struct tpm_chip *chip)
|
||||
static int tpm_continue_selftest(struct tpm_chip *chip)
|
||||
{
|
||||
int rc;
|
||||
struct tpm_cmd_t cmd;
|
||||
|
@ -637,7 +637,6 @@ int tpm_continue_selftest(struct tpm_chip *chip)
|
|||
"continue selftest");
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tpm_continue_selftest);
|
||||
|
||||
ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr,
|
||||
char *buf)
|
||||
|
@ -732,7 +731,7 @@ static struct tpm_input_header pcrread_header = {
|
|||
.ordinal = TPM_ORDINAL_PCRREAD
|
||||
};
|
||||
|
||||
int __tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
|
||||
static int __tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
|
||||
{
|
||||
int rc;
|
||||
struct tpm_cmd_t cmd;
|
||||
|
@ -812,6 +811,45 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(tpm_pcr_extend);
|
||||
|
||||
/**
|
||||
* tpm_do_selftest - have the TPM continue its selftest and wait until it
|
||||
* can receive further commands
|
||||
* @chip: TPM chip to use
|
||||
*
|
||||
* Returns 0 on success, < 0 in case of fatal error or a value > 0 representing
|
||||
* a TPM error code.
|
||||
*/
|
||||
int tpm_do_selftest(struct tpm_chip *chip)
|
||||
{
|
||||
int rc;
|
||||
u8 digest[TPM_DIGEST_SIZE];
|
||||
unsigned int loops;
|
||||
unsigned int delay_msec = 1000;
|
||||
unsigned long duration;
|
||||
|
||||
duration = tpm_calc_ordinal_duration(chip,
|
||||
TPM_ORD_CONTINUE_SELFTEST);
|
||||
|
||||
loops = jiffies_to_msecs(duration) / delay_msec;
|
||||
|
||||
rc = tpm_continue_selftest(chip);
|
||||
/* This may fail if there was no TPM driver during a suspend/resume
|
||||
* cycle; some may return 10 (BAD_ORDINAL), others 28 (FAILEDSELFTEST)
|
||||
*/
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
do {
|
||||
rc = __tpm_pcr_read(chip, 0, digest);
|
||||
if (rc != TPM_WARN_DOING_SELFTEST)
|
||||
return rc;
|
||||
msleep(delay_msec);
|
||||
} while (--loops > 0);
|
||||
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tpm_do_selftest);
|
||||
|
||||
int tpm_send(u32 chip_num, void *cmd, size_t buflen)
|
||||
{
|
||||
struct tpm_chip *chip;
|
||||
|
|
|
@ -38,6 +38,8 @@ enum tpm_addr {
|
|||
TPM_ADDR = 0x4E,
|
||||
};
|
||||
|
||||
#define TPM_WARN_DOING_SELFTEST 0x802
|
||||
|
||||
extern ssize_t tpm_show_pubek(struct device *, struct device_attribute *attr,
|
||||
char *);
|
||||
extern ssize_t tpm_show_pcrs(struct device *, struct device_attribute *attr,
|
||||
|
@ -281,7 +283,7 @@ ssize_t tpm_getcap(struct device *, __be32, cap_t *, const char *);
|
|||
|
||||
extern int tpm_get_timeouts(struct tpm_chip *);
|
||||
extern void tpm_gen_interrupt(struct tpm_chip *);
|
||||
extern int tpm_continue_selftest(struct tpm_chip *);
|
||||
extern int tpm_do_selftest(struct tpm_chip *);
|
||||
extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32);
|
||||
extern struct tpm_chip* tpm_register_hardware(struct device *,
|
||||
const struct tpm_vendor_specific *);
|
||||
|
|
|
@ -616,6 +616,12 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
|
|||
/* get the timeouts before testing for irqs */
|
||||
tpm_get_timeouts(chip);
|
||||
|
||||
if (tpm_do_selftest(chip)) {
|
||||
dev_err(dev, "TPM self test failed\n");
|
||||
rc = -ENODEV;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
/* INTERRUPT Setup */
|
||||
init_waitqueue_head(&chip->vendor.read_queue);
|
||||
init_waitqueue_head(&chip->vendor.int_queue);
|
||||
|
@ -722,7 +728,6 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
|
|||
list_add(&chip->vendor.list, &tis_chips);
|
||||
spin_unlock(&tis_lock);
|
||||
|
||||
tpm_continue_selftest(chip);
|
||||
|
||||
return 0;
|
||||
out_err:
|
||||
|
@ -790,7 +795,7 @@ static int tpm_tis_pnp_resume(struct pnp_dev *dev)
|
|||
|
||||
ret = tpm_pm_resume(&dev->dev);
|
||||
if (!ret)
|
||||
tpm_continue_selftest(chip);
|
||||
tpm_do_selftest(chip);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue