mirror of
https://github.com/torvalds/linux.git
synced 2025-11-30 23:16:01 +07:00
Merge tag 'tpmdd-next-v6.18-2' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd
Pull tpm updates from Jarkko Sakkinen: - Disable TCG_TPM2_HMAC from defconfig It causes performance issues, and breaks some atypical configurations. - simplify code using the new crypto library - misc fixes and cleanups * tag 'tpmdd-next-v6.18-2' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd: tpm: Prevent local DOS via tpm/tpm0/ppi/*operations tpm: use a map for tpm2_calc_ordinal_duration() tpm_tis: Fix incorrect arguments in tpm_tis_probe_irq_single tpm: Use HMAC-SHA256 library instead of open-coded HMAC tpm: Compare HMAC values in constant time tpm: Disable TPM2_TCG_HMAC by default
This commit is contained in:
@@ -29,10 +29,11 @@ if TCG_TPM
|
||||
|
||||
config TCG_TPM2_HMAC
|
||||
bool "Use HMAC and encrypted transactions on the TPM bus"
|
||||
default X86_64
|
||||
default n
|
||||
select CRYPTO_ECDH
|
||||
select CRYPTO_LIB_AESCFB
|
||||
select CRYPTO_LIB_SHA256
|
||||
select CRYPTO_LIB_UTILS
|
||||
help
|
||||
Setting this causes us to deploy a scheme which uses request
|
||||
and response HMACs in addition to encryption for
|
||||
|
||||
@@ -52,7 +52,7 @@ MODULE_PARM_DESC(suspend_pcr,
|
||||
unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
|
||||
{
|
||||
if (chip->flags & TPM_CHIP_FLAG_TPM2)
|
||||
return tpm2_calc_ordinal_duration(chip, ordinal);
|
||||
return tpm2_calc_ordinal_duration(ordinal);
|
||||
else
|
||||
return tpm1_calc_ordinal_duration(chip, ordinal);
|
||||
}
|
||||
|
||||
@@ -299,7 +299,7 @@ ssize_t tpm2_get_tpm_pt(struct tpm_chip *chip, u32 property_id,
|
||||
ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip);
|
||||
int tpm2_auto_startup(struct tpm_chip *chip);
|
||||
void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type);
|
||||
unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
|
||||
unsigned long tpm2_calc_ordinal_duration(u32 ordinal);
|
||||
int tpm2_probe(struct tpm_chip *chip);
|
||||
int tpm2_get_cc_attrs_tbl(struct tpm_chip *chip);
|
||||
int tpm2_find_cc(struct tpm_chip *chip, u32 cc);
|
||||
|
||||
@@ -28,120 +28,57 @@ static struct tpm2_hash tpm2_hash_map[] = {
|
||||
|
||||
int tpm2_get_timeouts(struct tpm_chip *chip)
|
||||
{
|
||||
/* Fixed timeouts for TPM2 */
|
||||
chip->timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A);
|
||||
chip->timeout_b = msecs_to_jiffies(TPM2_TIMEOUT_B);
|
||||
chip->timeout_c = msecs_to_jiffies(TPM2_TIMEOUT_C);
|
||||
chip->timeout_d = msecs_to_jiffies(TPM2_TIMEOUT_D);
|
||||
|
||||
/* PTP spec timeouts */
|
||||
chip->duration[TPM_SHORT] = msecs_to_jiffies(TPM2_DURATION_SHORT);
|
||||
chip->duration[TPM_MEDIUM] = msecs_to_jiffies(TPM2_DURATION_MEDIUM);
|
||||
chip->duration[TPM_LONG] = msecs_to_jiffies(TPM2_DURATION_LONG);
|
||||
|
||||
/* Key creation commands long timeouts */
|
||||
chip->duration[TPM_LONG_LONG] =
|
||||
msecs_to_jiffies(TPM2_DURATION_LONG_LONG);
|
||||
|
||||
chip->flags |= TPM_CHIP_FLAG_HAVE_TIMEOUTS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* tpm2_ordinal_duration_index() - returns an index to the chip duration table
|
||||
* @ordinal: TPM command ordinal.
|
||||
*
|
||||
* The function returns an index to the chip duration table
|
||||
* (enum tpm_duration), that describes the maximum amount of
|
||||
* time the chip could take to return the result for a particular ordinal.
|
||||
*
|
||||
* The values of the MEDIUM, and LONG durations are taken
|
||||
* from the PC Client Profile (PTP) specification (750, 2000 msec)
|
||||
*
|
||||
* LONG_LONG is for commands that generates keys which empirically takes
|
||||
* a longer time on some systems.
|
||||
*
|
||||
* Return:
|
||||
* * TPM_MEDIUM
|
||||
* * TPM_LONG
|
||||
* * TPM_LONG_LONG
|
||||
* * TPM_UNDEFINED
|
||||
/*
|
||||
* Contains the maximum durations in milliseconds for TPM2 commands.
|
||||
*/
|
||||
static u8 tpm2_ordinal_duration_index(u32 ordinal)
|
||||
{
|
||||
switch (ordinal) {
|
||||
/* Startup */
|
||||
case TPM2_CC_STARTUP: /* 144 */
|
||||
return TPM_MEDIUM;
|
||||
|
||||
case TPM2_CC_SELF_TEST: /* 143 */
|
||||
return TPM_LONG;
|
||||
|
||||
case TPM2_CC_GET_RANDOM: /* 17B */
|
||||
return TPM_LONG;
|
||||
|
||||
case TPM2_CC_SEQUENCE_UPDATE: /* 15C */
|
||||
return TPM_MEDIUM;
|
||||
case TPM2_CC_SEQUENCE_COMPLETE: /* 13E */
|
||||
return TPM_MEDIUM;
|
||||
case TPM2_CC_EVENT_SEQUENCE_COMPLETE: /* 185 */
|
||||
return TPM_MEDIUM;
|
||||
case TPM2_CC_HASH_SEQUENCE_START: /* 186 */
|
||||
return TPM_MEDIUM;
|
||||
|
||||
case TPM2_CC_VERIFY_SIGNATURE: /* 177 */
|
||||
return TPM_LONG_LONG;
|
||||
|
||||
case TPM2_CC_PCR_EXTEND: /* 182 */
|
||||
return TPM_MEDIUM;
|
||||
|
||||
case TPM2_CC_HIERARCHY_CONTROL: /* 121 */
|
||||
return TPM_LONG;
|
||||
case TPM2_CC_HIERARCHY_CHANGE_AUTH: /* 129 */
|
||||
return TPM_LONG;
|
||||
|
||||
case TPM2_CC_GET_CAPABILITY: /* 17A */
|
||||
return TPM_MEDIUM;
|
||||
|
||||
case TPM2_CC_NV_READ: /* 14E */
|
||||
return TPM_LONG;
|
||||
|
||||
case TPM2_CC_CREATE_PRIMARY: /* 131 */
|
||||
return TPM_LONG_LONG;
|
||||
case TPM2_CC_CREATE: /* 153 */
|
||||
return TPM_LONG_LONG;
|
||||
case TPM2_CC_CREATE_LOADED: /* 191 */
|
||||
return TPM_LONG_LONG;
|
||||
|
||||
default:
|
||||
return TPM_UNDEFINED;
|
||||
}
|
||||
}
|
||||
static const struct {
|
||||
unsigned long ordinal;
|
||||
unsigned long duration;
|
||||
} tpm2_ordinal_duration_map[] = {
|
||||
{TPM2_CC_STARTUP, 750},
|
||||
{TPM2_CC_SELF_TEST, 3000},
|
||||
{TPM2_CC_GET_RANDOM, 2000},
|
||||
{TPM2_CC_SEQUENCE_UPDATE, 750},
|
||||
{TPM2_CC_SEQUENCE_COMPLETE, 750},
|
||||
{TPM2_CC_EVENT_SEQUENCE_COMPLETE, 750},
|
||||
{TPM2_CC_HASH_SEQUENCE_START, 750},
|
||||
{TPM2_CC_VERIFY_SIGNATURE, 30000},
|
||||
{TPM2_CC_PCR_EXTEND, 750},
|
||||
{TPM2_CC_HIERARCHY_CONTROL, 2000},
|
||||
{TPM2_CC_HIERARCHY_CHANGE_AUTH, 2000},
|
||||
{TPM2_CC_GET_CAPABILITY, 750},
|
||||
{TPM2_CC_NV_READ, 2000},
|
||||
{TPM2_CC_CREATE_PRIMARY, 30000},
|
||||
{TPM2_CC_CREATE, 30000},
|
||||
{TPM2_CC_CREATE_LOADED, 30000},
|
||||
};
|
||||
|
||||
/**
|
||||
* tpm2_calc_ordinal_duration() - calculate the maximum command duration
|
||||
* @chip: TPM chip to use.
|
||||
* tpm2_calc_ordinal_duration() - Calculate the maximum command duration
|
||||
* @ordinal: TPM command ordinal.
|
||||
*
|
||||
* The function returns the maximum amount of time the chip could take
|
||||
* to return the result for a particular ordinal in jiffies.
|
||||
*
|
||||
* Return: A maximal duration time for an ordinal in jiffies.
|
||||
* Returns the maximum amount of time the chip is expected by kernel to
|
||||
* take in jiffies.
|
||||
*/
|
||||
unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
|
||||
unsigned long tpm2_calc_ordinal_duration(u32 ordinal)
|
||||
{
|
||||
unsigned int index;
|
||||
int i;
|
||||
|
||||
index = tpm2_ordinal_duration_index(ordinal);
|
||||
for (i = 0; i < ARRAY_SIZE(tpm2_ordinal_duration_map); i++)
|
||||
if (ordinal == tpm2_ordinal_duration_map[i].ordinal)
|
||||
return msecs_to_jiffies(tpm2_ordinal_duration_map[i].duration);
|
||||
|
||||
if (index != TPM_UNDEFINED)
|
||||
return chip->duration[index];
|
||||
else
|
||||
return msecs_to_jiffies(TPM2_DURATION_DEFAULT);
|
||||
return msecs_to_jiffies(TPM2_DURATION_DEFAULT);
|
||||
}
|
||||
|
||||
|
||||
struct tpm2_pcr_read_out {
|
||||
__be32 update_cnt;
|
||||
__be32 pcr_selects_cnt;
|
||||
|
||||
@@ -69,8 +69,8 @@
|
||||
#include <linux/unaligned.h>
|
||||
#include <crypto/kpp.h>
|
||||
#include <crypto/ecdh.h>
|
||||
#include <crypto/hash.h>
|
||||
#include <crypto/hmac.h>
|
||||
#include <crypto/sha2.h>
|
||||
#include <crypto/utils.h>
|
||||
|
||||
/* maximum number of names the TPM must remember for authorization */
|
||||
#define AUTH_MAX_NAMES 3
|
||||
@@ -384,51 +384,6 @@ EXPORT_SYMBOL_GPL(tpm_buf_append_hmac_session);
|
||||
static int tpm2_create_primary(struct tpm_chip *chip, u32 hierarchy,
|
||||
u32 *handle, u8 *name);
|
||||
|
||||
/*
|
||||
* It turns out the crypto hmac(sha256) is hard for us to consume
|
||||
* because it assumes a fixed key and the TPM seems to change the key
|
||||
* on every operation, so we weld the hmac init and final functions in
|
||||
* here to give it the same usage characteristics as a regular hash
|
||||
*/
|
||||
static void tpm2_hmac_init(struct sha256_ctx *sctx, u8 *key, u32 key_len)
|
||||
{
|
||||
u8 pad[SHA256_BLOCK_SIZE];
|
||||
int i;
|
||||
|
||||
sha256_init(sctx);
|
||||
for (i = 0; i < sizeof(pad); i++) {
|
||||
if (i < key_len)
|
||||
pad[i] = key[i];
|
||||
else
|
||||
pad[i] = 0;
|
||||
pad[i] ^= HMAC_IPAD_VALUE;
|
||||
}
|
||||
sha256_update(sctx, pad, sizeof(pad));
|
||||
}
|
||||
|
||||
static void tpm2_hmac_final(struct sha256_ctx *sctx, u8 *key, u32 key_len,
|
||||
u8 *out)
|
||||
{
|
||||
u8 pad[SHA256_BLOCK_SIZE];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(pad); i++) {
|
||||
if (i < key_len)
|
||||
pad[i] = key[i];
|
||||
else
|
||||
pad[i] = 0;
|
||||
pad[i] ^= HMAC_OPAD_VALUE;
|
||||
}
|
||||
|
||||
/* collect the final hash; use out as temporary storage */
|
||||
sha256_final(sctx, out);
|
||||
|
||||
sha256_init(sctx);
|
||||
sha256_update(sctx, pad, sizeof(pad));
|
||||
sha256_update(sctx, out, SHA256_DIGEST_SIZE);
|
||||
sha256_final(sctx, out);
|
||||
}
|
||||
|
||||
/*
|
||||
* assume hash sha256 and nonces u, v of size SHA256_DIGEST_SIZE but
|
||||
* otherwise standard tpm2_KDFa. Note output is in bytes not bits.
|
||||
@@ -440,16 +395,16 @@ static void tpm2_KDFa(u8 *key, u32 key_len, const char *label, u8 *u,
|
||||
const __be32 bits = cpu_to_be32(bytes * 8);
|
||||
|
||||
while (bytes > 0) {
|
||||
struct sha256_ctx sctx;
|
||||
struct hmac_sha256_ctx hctx;
|
||||
__be32 c = cpu_to_be32(counter);
|
||||
|
||||
tpm2_hmac_init(&sctx, key, key_len);
|
||||
sha256_update(&sctx, (u8 *)&c, sizeof(c));
|
||||
sha256_update(&sctx, label, strlen(label)+1);
|
||||
sha256_update(&sctx, u, SHA256_DIGEST_SIZE);
|
||||
sha256_update(&sctx, v, SHA256_DIGEST_SIZE);
|
||||
sha256_update(&sctx, (u8 *)&bits, sizeof(bits));
|
||||
tpm2_hmac_final(&sctx, key, key_len, out);
|
||||
hmac_sha256_init_usingrawkey(&hctx, key, key_len);
|
||||
hmac_sha256_update(&hctx, (u8 *)&c, sizeof(c));
|
||||
hmac_sha256_update(&hctx, label, strlen(label) + 1);
|
||||
hmac_sha256_update(&hctx, u, SHA256_DIGEST_SIZE);
|
||||
hmac_sha256_update(&hctx, v, SHA256_DIGEST_SIZE);
|
||||
hmac_sha256_update(&hctx, (u8 *)&bits, sizeof(bits));
|
||||
hmac_sha256_final(&hctx, out);
|
||||
|
||||
bytes -= SHA256_DIGEST_SIZE;
|
||||
counter++;
|
||||
@@ -593,6 +548,7 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf)
|
||||
u32 attrs;
|
||||
u8 cphash[SHA256_DIGEST_SIZE];
|
||||
struct sha256_ctx sctx;
|
||||
struct hmac_sha256_ctx hctx;
|
||||
|
||||
if (!auth)
|
||||
return;
|
||||
@@ -704,14 +660,14 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf)
|
||||
sha256_final(&sctx, cphash);
|
||||
|
||||
/* now calculate the hmac */
|
||||
tpm2_hmac_init(&sctx, auth->session_key, sizeof(auth->session_key)
|
||||
+ auth->passphrase_len);
|
||||
sha256_update(&sctx, cphash, sizeof(cphash));
|
||||
sha256_update(&sctx, auth->our_nonce, sizeof(auth->our_nonce));
|
||||
sha256_update(&sctx, auth->tpm_nonce, sizeof(auth->tpm_nonce));
|
||||
sha256_update(&sctx, &auth->attrs, 1);
|
||||
tpm2_hmac_final(&sctx, auth->session_key, sizeof(auth->session_key)
|
||||
+ auth->passphrase_len, hmac);
|
||||
hmac_sha256_init_usingrawkey(&hctx, auth->session_key,
|
||||
sizeof(auth->session_key) +
|
||||
auth->passphrase_len);
|
||||
hmac_sha256_update(&hctx, cphash, sizeof(cphash));
|
||||
hmac_sha256_update(&hctx, auth->our_nonce, sizeof(auth->our_nonce));
|
||||
hmac_sha256_update(&hctx, auth->tpm_nonce, sizeof(auth->tpm_nonce));
|
||||
hmac_sha256_update(&hctx, &auth->attrs, 1);
|
||||
hmac_sha256_final(&hctx, hmac);
|
||||
}
|
||||
EXPORT_SYMBOL(tpm_buf_fill_hmac_session);
|
||||
|
||||
@@ -751,6 +707,7 @@ int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf,
|
||||
u8 rphash[SHA256_DIGEST_SIZE];
|
||||
u32 attrs, cc;
|
||||
struct sha256_ctx sctx;
|
||||
struct hmac_sha256_ctx hctx;
|
||||
u16 tag = be16_to_cpu(head->tag);
|
||||
int parm_len, len, i, handles;
|
||||
|
||||
@@ -820,21 +777,20 @@ int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf,
|
||||
sha256_final(&sctx, rphash);
|
||||
|
||||
/* now calculate the hmac */
|
||||
tpm2_hmac_init(&sctx, auth->session_key, sizeof(auth->session_key)
|
||||
+ auth->passphrase_len);
|
||||
sha256_update(&sctx, rphash, sizeof(rphash));
|
||||
sha256_update(&sctx, auth->tpm_nonce, sizeof(auth->tpm_nonce));
|
||||
sha256_update(&sctx, auth->our_nonce, sizeof(auth->our_nonce));
|
||||
sha256_update(&sctx, &auth->attrs, 1);
|
||||
hmac_sha256_init_usingrawkey(&hctx, auth->session_key,
|
||||
sizeof(auth->session_key) +
|
||||
auth->passphrase_len);
|
||||
hmac_sha256_update(&hctx, rphash, sizeof(rphash));
|
||||
hmac_sha256_update(&hctx, auth->tpm_nonce, sizeof(auth->tpm_nonce));
|
||||
hmac_sha256_update(&hctx, auth->our_nonce, sizeof(auth->our_nonce));
|
||||
hmac_sha256_update(&hctx, &auth->attrs, 1);
|
||||
/* we're done with the rphash, so put our idea of the hmac there */
|
||||
tpm2_hmac_final(&sctx, auth->session_key, sizeof(auth->session_key)
|
||||
+ auth->passphrase_len, rphash);
|
||||
if (memcmp(rphash, &buf->data[offset_s], SHA256_DIGEST_SIZE) == 0) {
|
||||
rc = 0;
|
||||
} else {
|
||||
hmac_sha256_final(&hctx, rphash);
|
||||
if (crypto_memneq(rphash, &buf->data[offset_s], SHA256_DIGEST_SIZE)) {
|
||||
dev_err(&chip->dev, "TPM: HMAC check failed\n");
|
||||
goto out;
|
||||
}
|
||||
rc = 0;
|
||||
|
||||
/* now do response decryption */
|
||||
if (auth->attrs & TPM2_SA_ENCRYPT) {
|
||||
|
||||
@@ -33,6 +33,20 @@ static const guid_t tpm_ppi_guid =
|
||||
GUID_INIT(0x3DDDFAA6, 0x361B, 0x4EB4,
|
||||
0xA4, 0x24, 0x8D, 0x10, 0x08, 0x9D, 0x16, 0x53);
|
||||
|
||||
static const char * const tpm_ppi_info[] = {
|
||||
"Not implemented",
|
||||
"BIOS only",
|
||||
"Blocked for OS by system firmware",
|
||||
"User required",
|
||||
"User not required",
|
||||
};
|
||||
|
||||
/* A spinlock to protect access to the cache from concurrent reads */
|
||||
static DEFINE_MUTEX(tpm_ppi_lock);
|
||||
|
||||
static u32 ppi_operations_cache[PPI_VS_REQ_END + 1];
|
||||
static bool ppi_cache_populated;
|
||||
|
||||
static bool tpm_ppi_req_has_parameter(u64 req)
|
||||
{
|
||||
return req == 23;
|
||||
@@ -277,8 +291,7 @@ cleanup:
|
||||
return status;
|
||||
}
|
||||
|
||||
static ssize_t show_ppi_operations(acpi_handle dev_handle, char *buf, u32 start,
|
||||
u32 end)
|
||||
static ssize_t cache_ppi_operations(acpi_handle dev_handle, char *buf)
|
||||
{
|
||||
int i;
|
||||
u32 ret;
|
||||
@@ -286,34 +299,22 @@ static ssize_t show_ppi_operations(acpi_handle dev_handle, char *buf, u32 start,
|
||||
union acpi_object *obj, tmp;
|
||||
union acpi_object argv = ACPI_INIT_DSM_ARGV4(1, &tmp);
|
||||
|
||||
static char *info[] = {
|
||||
"Not implemented",
|
||||
"BIOS only",
|
||||
"Blocked for OS by BIOS",
|
||||
"User required",
|
||||
"User not required",
|
||||
};
|
||||
|
||||
if (!acpi_check_dsm(dev_handle, &tpm_ppi_guid, TPM_PPI_REVISION_ID_1,
|
||||
1 << TPM_PPI_FN_GETOPR))
|
||||
return -EPERM;
|
||||
|
||||
tmp.integer.type = ACPI_TYPE_INTEGER;
|
||||
for (i = start; i <= end; i++) {
|
||||
for (i = 0; i <= PPI_VS_REQ_END; i++) {
|
||||
tmp.integer.value = i;
|
||||
obj = tpm_eval_dsm(dev_handle, TPM_PPI_FN_GETOPR,
|
||||
ACPI_TYPE_INTEGER, &argv,
|
||||
TPM_PPI_REVISION_ID_1);
|
||||
if (!obj) {
|
||||
if (!obj)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
ret = obj->integer.value;
|
||||
ACPI_FREE(obj);
|
||||
}
|
||||
|
||||
if (ret > 0 && ret < ARRAY_SIZE(info))
|
||||
len += sysfs_emit_at(buf, len, "%d %d: %s\n",
|
||||
i, ret, info[ret]);
|
||||
ret = obj->integer.value;
|
||||
ppi_operations_cache[i] = ret;
|
||||
ACPI_FREE(obj);
|
||||
}
|
||||
|
||||
return len;
|
||||
@@ -324,9 +325,30 @@ static ssize_t tpm_show_ppi_tcg_operations(struct device *dev,
|
||||
char *buf)
|
||||
{
|
||||
struct tpm_chip *chip = to_tpm_chip(dev);
|
||||
ssize_t len = 0;
|
||||
u32 ret;
|
||||
int i;
|
||||
|
||||
return show_ppi_operations(chip->acpi_dev_handle, buf, 0,
|
||||
PPI_TPM_REQ_MAX);
|
||||
mutex_lock(&tpm_ppi_lock);
|
||||
if (!ppi_cache_populated) {
|
||||
len = cache_ppi_operations(chip->acpi_dev_handle, buf);
|
||||
if (len < 0) {
|
||||
mutex_unlock(&tpm_ppi_lock);
|
||||
return len;
|
||||
}
|
||||
|
||||
ppi_cache_populated = true;
|
||||
}
|
||||
|
||||
for (i = 0; i <= PPI_TPM_REQ_MAX; i++) {
|
||||
ret = ppi_operations_cache[i];
|
||||
if (ret >= 0 && ret < ARRAY_SIZE(tpm_ppi_info))
|
||||
len += sysfs_emit_at(buf, len, "%d %d: %s\n",
|
||||
i, ret, tpm_ppi_info[ret]);
|
||||
}
|
||||
mutex_unlock(&tpm_ppi_lock);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t tpm_show_ppi_vs_operations(struct device *dev,
|
||||
@@ -334,9 +356,30 @@ static ssize_t tpm_show_ppi_vs_operations(struct device *dev,
|
||||
char *buf)
|
||||
{
|
||||
struct tpm_chip *chip = to_tpm_chip(dev);
|
||||
ssize_t len = 0;
|
||||
u32 ret;
|
||||
int i;
|
||||
|
||||
return show_ppi_operations(chip->acpi_dev_handle, buf, PPI_VS_REQ_START,
|
||||
PPI_VS_REQ_END);
|
||||
mutex_lock(&tpm_ppi_lock);
|
||||
if (!ppi_cache_populated) {
|
||||
len = cache_ppi_operations(chip->acpi_dev_handle, buf);
|
||||
if (len < 0) {
|
||||
mutex_unlock(&tpm_ppi_lock);
|
||||
return len;
|
||||
}
|
||||
|
||||
ppi_cache_populated = true;
|
||||
}
|
||||
|
||||
for (i = PPI_VS_REQ_START; i <= PPI_VS_REQ_END; i++) {
|
||||
ret = ppi_operations_cache[i];
|
||||
if (ret >= 0 && ret < ARRAY_SIZE(tpm_ppi_info))
|
||||
len += sysfs_emit_at(buf, len, "%d %d: %s\n",
|
||||
i, ret, tpm_ppi_info[ret]);
|
||||
}
|
||||
mutex_unlock(&tpm_ppi_lock);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(version, S_IRUGO, tpm_show_ppi_version, NULL);
|
||||
|
||||
@@ -978,8 +978,8 @@ restore_irqs:
|
||||
* will call disable_irq which undoes all of the above.
|
||||
*/
|
||||
if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
|
||||
tpm_tis_write8(priv, original_int_vec,
|
||||
TPM_INT_VECTOR(priv->locality));
|
||||
tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality),
|
||||
original_int_vec);
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -228,10 +228,11 @@ enum tpm2_timeouts {
|
||||
TPM2_TIMEOUT_B = 4000,
|
||||
TPM2_TIMEOUT_C = 200,
|
||||
TPM2_TIMEOUT_D = 30,
|
||||
};
|
||||
|
||||
enum tpm2_durations {
|
||||
TPM2_DURATION_SHORT = 20,
|
||||
TPM2_DURATION_MEDIUM = 750,
|
||||
TPM2_DURATION_LONG = 2000,
|
||||
TPM2_DURATION_LONG_LONG = 300000,
|
||||
TPM2_DURATION_DEFAULT = 120000,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user