Skip to content

Commit e46e22f

Browse files
naynajainJarkko Sakkinen
authored andcommitted
tpm: enhance read_log_of() to support Physical TPM event log
Physical TPMs use Open Firmware Device Tree bindings that are similar to the IBM Power virtual TPM to support event log. However, these properties store the values in different endianness for Physical and Virtual TPM. This patch fixes the endianness issue by doing appropriate conversion based on Physical or Virtual TPM. Signed-off-by: Nayna Jain <nayna@linux.vnet.ibm.com> Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Tested-by: Kenneth Goldman <kgold@linux.vnet.ibm.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
1 parent c1f92b4 commit e46e22f

File tree

1 file changed

+23
-4
lines changed

1 file changed

+23
-4
lines changed

drivers/char/tpm/tpm_of.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ int tpm_read_log_of(struct tpm_chip *chip)
2727
const u32 *sizep;
2828
const u64 *basep;
2929
struct tpm_bios_log *log;
30+
u32 size;
31+
u64 base;
3032

3133
log = &chip->log;
3234
if (chip->dev.parent && chip->dev.parent->of_node)
@@ -41,18 +43,35 @@ int tpm_read_log_of(struct tpm_chip *chip)
4143
if (sizep == NULL || basep == NULL)
4244
return -EIO;
4345

44-
if (*sizep == 0) {
46+
/*
47+
* For both vtpm/tpm, firmware has log addr and log size in big
48+
* endian format. But in case of vtpm, there is a method called
49+
* sml-handover which is run during kernel init even before
50+
* device tree is setup. This sml-handover function takes care
51+
* of endianness and writes to sml-base and sml-size in little
52+
* endian format. For this reason, vtpm doesn't need conversion
53+
* but physical tpm needs the conversion.
54+
*/
55+
if (of_property_match_string(np, "compatible", "IBM,vtpm") < 0) {
56+
size = be32_to_cpup(sizep);
57+
base = be64_to_cpup(basep);
58+
} else {
59+
size = *sizep;
60+
base = *basep;
61+
}
62+
63+
if (size == 0) {
4564
dev_warn(&chip->dev, "%s: Event log area empty\n", __func__);
4665
return -EIO;
4766
}
4867

49-
log->bios_event_log = kmalloc(*sizep, GFP_KERNEL);
68+
log->bios_event_log = kmalloc(size, GFP_KERNEL);
5069
if (!log->bios_event_log)
5170
return -ENOMEM;
5271

53-
log->bios_event_log_end = log->bios_event_log + *sizep;
72+
log->bios_event_log_end = log->bios_event_log + size;
5473

55-
memcpy(log->bios_event_log, __va(*basep), *sizep);
74+
memcpy(log->bios_event_log, __va(base), size);
5675

5776
return 0;
5877
}

0 commit comments

Comments
 (0)